Codex macOS: Cmd+Shift+N with six windows crashes/reloads existing windows and loses their thread routes

Resolved 💬 2 comments Opened Jul 16, 2026 by nachoal Closed Jul 16, 2026

What version of the Codex App are you using?

26.707.72221 (bundle build 5307)

Bundle ID: com.openai.codex

What subscription do you have?

ChatGPT paid plan.

What platform is your computer?

  • macOS 26.5.2 (25F84)
  • Darwin 25.5.0
  • Apple Silicon (arm64)
  • 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 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 and is distinct from older general Desktop reset reports because it has a repeatable multi-window trigger.

What steps can reproduce the bug?

  1. Open six primary ChatGPT/Codex windows.
  2. Navigate each window to a different Codex thread. Some threads may have active/background work.
  3. Press Cmd+Shift+N to open a seventh primary window.
  4. The new window opens normally.
  5. Within roughly 25–50 seconds, observe 2–4 pre-existing windows reload/reset.
  6. 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:

  1. Opening the seventh window is followed by crashes of multiple existing renderer processes.
  2. The app automatically reloads those renderers.
  3. Recovery does not restore each window's prior thread route.
  4. App-server work continues, but the user loses visible ownership/context for those threads.

After the reloads, the Desktop log also contains state-desynchronization signatures:

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
  1. Persist each BrowserWindow's current route/thread ID in the main process and restore it after renderer reload.
  2. Durably log render-process-gone reason, exit code, window ID, and webContents ID before uploading telemetry.
  3. Rehydrate the displayed conversation and active turn before applying queued app-server events after recovery.
  4. Investigate the memory impact of duplicating conversation state and broadcasting all app-server events across every renderer window.
  5. 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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗