Codex macOS: Cmd+Shift+N with six windows crashes/reloads existing windows and loses their thread routes
What version of the Codex App are you using (From “About Codex” dialog)?
26.707.72221 (bundle build 5307)Bundle ID: com.openai.codex
What subscription do you have?
ChatGPT paid plan
What platform is your computer?
Darwin 25.5.0 arm64 armmacOS 26.5.2 (25F84)MacBook Pro, M3 Max, 128 GB RAM
What issue are you seeing?
When six ChatGPT/Codex windows are already open on different Codex threads, pressing Cmd+Shift+N to open a seventh window causes a random group of approximately 2–4 existing windows to reload/reset.
The backend conversations and Codex turns continue running, but the affected windows lose the thread/conversation route they were displaying. There is no reliable Back path. Unless I remember which thread each window had open, I lose the window-to-thread mapping and must search manually.
This causes significant productivity and context loss during parallel Codex work. It is not thread deletion; it is loss of renderer/window UI state while backend work continues.
This appears to be a recent regression in the merged ChatGPT/Codex macOS app. It has a repeatable multi-window trigger and should be tracked separately from older general Desktop reset reports.
What steps can reproduce the bug?
- Open six primary ChatGPT/Codex windows.
- Navigate each window to a different Codex thread. Some threads may have active/background work.
- Press Cmd+Shift+N to open a seventh primary window.
- The new window opens normally.
- Within roughly 25–50 seconds, observe 2–4 pre-existing windows reload/reset.
- The affected windows no longer show the threads they previously owned, although those threads continue in the background.
In the captured incident, exactly three existing windows reloaded.
What is the expected behavior?
Opening a new Codex window must not crash, reload, replace, or reset any existing window.
If a renderer nevertheless crashes, that window must recover to the exact thread and route it displayed before the crash, including any active turn state. The window-to-thread mapping must not be lost.
Additional information
I performed a read-only inspection without restarting, modifying, or reproducing against the running app.
Captured incident timeline
The same Desktop main process remained alive throughout:
05:07:55.115Z created/loaded new primary window: windowId=62 webContentsId=67
05:07:57.636Z new window renderer routes mounted
05:08:20.260Z existing windowId=23 webContentsId=24 renderer routes mounted again
05:08:45.251Z existing windowId=17 webContentsId=17 renderer routes mounted again
05:08:47.304Z existing windowId=45 webContentsId=49 renderer routes mounted again
The existing-window remounts reused their original BrowserWindow/webContents IDs and had no matching new-window creation events. This rules out intentional window replacement and identifies renderer reloads.
Crashpad created three corresponding renderer sidecars:
{"osarch":"arm64","ptype":"renderer"}
- one at local 23:08:17
- two at local 23:08:42
This matches the one-then-two existing-window remount sequence.
Confirmed immediate cause
Read-only inspection of the exact packaged build shows:
- Cmd+Shift+N creates a fresh BrowserWindow; there is no six-window cap or intentional eviction/reuse path.
- Every window installs a render-process-gone handler.
- On a non-clean renderer exit, the recovery path calls webContents.reload() after 500 ms.
- The reload path does not durably preserve and restore that window's current thread route.
The immediate failure mechanism is therefore:
- Opening the seventh window is followed by crashes of multiple existing renderer processes.
- The app automatically reloads those renderers.
- Recovery does not restore each window's prior thread route.
- App-server work continues, but the user loses visible ownership/context for those threads.
After the reloads, the Desktop log also contains:
Received item/started for unknown conversation
Received item/completed for unknown conversation
Conversation state not found
Item not found in turn state
Each renderer keeps independent conversation state, while app-server events are broadcast to all renderer windows. After reload, events can arrive before the affected renderer has rehydrated the conversation.
Remaining unknown
The underlying Chromium/Electron reason for the renderer crashes is not recoverable from the remaining local artifacts:
- render-process-gone reason and exit code are sent to Sentry but are not written to the durable plaintext Desktop log.
- Crashpad retained the renderer sidecars but not the local minidumps.
Post-incident renderer RSS was unusually high—approximately 1.3–2.8 GB per renderer—so renderer-local memory exhaustion or another Chromium/Electron renderer defect is plausible. It is not proven, and system-wide memory pressure was not present when inspected.
Suggested fix and instrumentation
- Persist each BrowserWindow's current route/thread ID in the main process and restore it after renderer reload.
- Durably log render-process-gone reason, exit code, window ID, and webContents ID before uploading telemetry.
- Rehydrate the displayed conversation and active turn before applying queued app-server events after recovery.
- Investigate the memory impact of duplicating conversation state and broadcasting all app-server events across every renderer window.
- Add a regression test: create seven primary windows, open a unique thread in each, simulate renderer exits for three existing windows, and verify each returns to its previous thread while backend work remains visible.
I am not attaching raw logs, session files, or minidumps publicly because they contain local paths and private thread metadata. I can provide sanitized excerpts or exact timestamps privately if helpful.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗