Codex App window exits when opening or resuming threads after auth_token_missing / browser pane initialization

Open 💬 2 comments Opened Aug 20, 2026 by nik65
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

26.818.2872.0

What subscription do you have?

ChatGPT Pro x20

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

On Codex App for Windows, opening or resuming a thread can make the primary Electron window disappear. There is no Windows Application Error, WER report, or crash dump.

The app logs show this sequence:

  1. thread/read and thread/resume succeed.
  2. A Browser Use host is created for the thread route (browserPane=true).
  3. The route window becomes unavailable (route window is not live, hasWindowState=false).
  4. Authentication falls back to auth_token_missing / HTTP 401 (Missing valid access token or actor biscuit / Unauthorized).
  5. IPC fails with EPIPE, then the app server stops with stop_process.

The issue reproduced repeatedly on the same day after reset, reinstall, and reboot, including with both old and newly created threads. Local thread rollouts and SQLite databases pass integrity checks, so this does not appear to be corruption of one conversation.

This may be related to #35740 / #35352, but there is no GPU process crash line in these logs, so I cannot confirm the same root cause.

What steps can reproduce the bug?

  1. Start Codex App on Windows.
  2. Open an existing thread, or create a new thread and navigate to it.
  3. The thread initially opens/resumes successfully.
  4. Within a few seconds, the main Codex window disappears.

Troubleshooting already performed:

  • Reinstalled the same Codex App version and rebooted Windows.
  • Verified JSON/JSONL state and SQLite databases; no corruption found.
  • Removed an old UTF-8 BOM from config.toml; TOML parsing succeeds.
  • Disabled features.computer_use, features.browser_use, and browser/computer-use plugins as a reversible diagnostic.
  • Ran codex exec --strict-config --ephemeral; configuration and ChatGPT authentication both succeeded.
  • The desktop app partially restored some browser/computer-use settings on startup, and navigating to a thread still reproduced the exit.

No local chat history or databases were deleted.

What is the expected behavior?

Opening or resuming a thread should keep the Codex window and app server running. If authentication expires, the app should show a recoverable sign-in error instead of losing the renderer/window and terminating the app server.

Additional information

Observed on Codex App 26.818.2872.0, Windows x64.

GitHub suggests #32040 as a potential duplicate. That issue covered Windows exits during in-app Browser/PiP initialization and was closed as fixed on July 17, 2026. The current reproduction is on the newer 26.818.2872.0 build, so it may be a regression. In this case, opening or resuming ordinary threads creates a browser-pane host and is followed by route-window loss, repeated auth_token_missing / HTTP 401 errors, EPIPE, and app-server stop_process.

A closely related report is #35740 (closed as duplicate of #35352). There is no explicit GPU-process crash line in the current logs, so I cannot confirm the same root cause.

no-active-thread-01a02047-94cd-7431-ad37-248f5a8d4ef4

View original on GitHub ↗

2 Comments

github-actions[bot] contributor · 7 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #39695
  • #39684
  • #39718
  • #39162

Powered by Codex Action

nik65 · 6 days ago

Follow-up diagnostics and local repair (Windows, 2026-08-21, Europe/Moscow)

I found a more specific local persistence failure in addition to the authentication/app restart symptoms.

Environment
-----------

  • Codex Windows package: 26.818.3698.0 (updated from 26.818.2872.0 at approximately 20:09 local time)
  • Desktop client reported by app-server: 26.818.31338
  • Command runner: 0.149.0-alpha.4
  • Windows x64, build 26200
  • Affected thread: 01a02557-d6e9-72e0-bc92-2fbd20e89a79

Direct thread-store evidence
-----------------------------
Before repair, read-only inspection of thread_history_1.sqlite showed:

  • projection state: next_rollout_byte_offset=409568, next_rollout_ordinal=46
  • projected thread_items: 16 rows, maximum rollout_ordinal=43
  • projected thread_turns: 1 row
  • SQLite quick_check: OK

The state database maps this thread to its canonical rollout JSONL. The JSONL around the failure is:

ordinal 43: event_msg
ordinal 44: response_item
ordinal 45: event_msg (token-count/rate-limit payload)
ordinal 45: event_msg (thread-settings payload)
ordinal 46: event_msg (turn-start payload)
ordinal 47: response_item

Therefore the projector can advance to expected ordinal 46 after the first ordinal-45 record, but the immediately following duplicate ordinal-45 record fails with:

thread-store internal error: thread history projection for
01a02557-d6e9-72e0-bc92-2fbd20e89a79 expected ordinal 46, got 45

This explains the repeated warning loop and the inability to persist or resume the thread. It is a logical projection/ordinal problem, not ordinary SQLite corruption. It is also consistent with the failure family described in upstream issues #35746 and #38792: derived thread-history state can become permanently out of sync with the canonical rollout.

Authentication and process lifecycle
-------------------------------------
The same incident also contains an independent auth failure:

getAuthStatus token refresh -> HTTP 401 Unauthorized
code: refresh_token_invalidated
message: Your refresh token has been invalidated. Please try signing in again.

This was followed by repeated Codex AppX container/process replacement. No Application Error, WER, .NET Runtime, or crash-dump event was recorded. The auth failure may trigger the bad recovery path, but it does not explain the duplicate ordinal by itself.

Safe local repair attempted
----------------------------
With Codex processes stopped, I created a backup of thread_history_1.sqlite and deleted only the derived rows for the affected thread from:

  • thread_history_projection_state
  • thread_items
  • thread_turns

The canonical rollout JSONL and other threads were not modified. This is the repair/workaround described by upstream issue #38792: the next resume should rebuild the derived projection from the durable rollout. The backup is retained locally as:

thread_history_1.sqlite.bak-20260821-issue39773

After restarting Codex, the application processes remained alive during the initial observation. The affected thread had not yet been opened again, so the rebuilt projection still needs to be verified on resume. If the current projector rejects the duplicate ordinal during a full rebuild, the product needs an idempotent/replayed-ordinal recovery path rather than treating the derived SQLite projection as authoritative.

Requested investigation
-----------------------

  1. Make thread-history materialization tolerate an exact replayed/duplicate boundary ordinal when the canonical JSONL proves it is the same persisted event, or rebuild the derived projection automatically from the rollout when the cursor is inconsistent.
  2. Validate the cursor against the rollout record at next_rollout_byte_offset before projecting more data; do not enter an endless expected-N/got-(N-1) loop.
  3. Treat OAuth refresh_token_invalidated as a recoverable sign-in state. The renderer/window and app-server should remain available to show a sign-in action instead of exiting/restarting the desktop app.
  4. Add a regression test covering two adjacent records with the same ordinal and a projection cursor that resumes at the second record, plus the existing malformed/direct-decoder cases from #35746.

Raw SQLite logs were not attached because they contain authentication headers/cookies. The sanitized observations above are reproducible from the local projection state and rollout structure without exposing credentials.

Local mitigation now applied
----------------------------
To prevent the Windows Desktop client from re-enabling the suspected route while this issue is investigated, I added a machine-level requirements.toml policy. It pins the following features to false for every local Codex client: in_app_browser, browser_use, browser_use_external, browser_use_full_cdp_access, computer_use, and multi_agent.

This uses the documented Windows managed-requirements location (%ProgramData%\\OpenAI\\Codex\\requirements.toml), rather than relying only on a user config.toml preference that the Desktop app can rewrite. The global Browser and Chrome bundled plugins are also disabled. Existing chats and canonical rollout files were not removed.

Because the server had already invalidated the saved OAuth refresh token, I moved the local auth.json to a same-directory backup and restarted Codex. This intentionally forces a fresh interactive sign-in; it does not revoke or expose credentials. The app should be evaluated only after that sign-in completes, using a new small chat first.

Related issues:

Live-validation update: a second Codex client was running at the same time from
the Windsurf IDE extension. The exact refresh_token_invalidated log entries
were attributed by process_uuid to that process (pid:35420), not to the
Desktop client's Codex process. The extension automatically respawned the
client after it was stopped, and both clients had been sharing
%USERPROFILE%\\.codex (auth, logs, and history).

For a practical temporary workaround, I configured Windsurf's
chatgpt.cliExecutable to invoke its bundled CLI through a small wrapper that
sets CODEX_HOME to a separate empty directory. This isolates its
authentication, logs, and thread history from Codex Desktop. Reload or restart
Windsurf before testing; Windsurf will require its own sign-in. Do not run both
clients against the same local Codex home while investigating this issue.