[macOS] 26.810.41047: main-process spawnSync storm respawns the plugin app-server ~5×/sec, freezing the UI and system input
What version of the Codex App are you using (From “About Codex” dialog)?
26.810.41047 (build 6570), macOS
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Darwin 25.5.0 arm64 arm — macOS 26.5.2 (25F84), Apple M4, 10 cores, 24 GB RAM
What issue are you seeing?
After the app auto-updated to 26.810.41047 on 2026-08-14 at 17:04 KST, the app becomes unusable within seconds of launch: the UI freezes, system-wide input lags, and CPU saturates.
The cause is a spawnSync storm in the Electron main process: the app repeatedly spawns Contents/Resources/codex (a 219 MB binary) synchronously, blocking the main thread.
1. Child-process churn (measured)
Sampling every ChatGPT-family process every 2 s for a 14-second window right after launch:
| t after launch | live Resources/codex children |
|---|---|
| +14 s | 19 |
| +16 s | 27 |
| +18 s | 21 |
| +20 s | 13 |
| +22 s | 2 |
| +24 s | 11 |
| +26 s | 16 |
| +28 s | 20 |
The PIDs are completely different at each snapshot — these are not long-lived workers:
- 75 unique
Resources/codexPIDs observed in that 14-second window - PID space advanced from
80731to81455(724 PIDs consumed) - ≈ 5 spawns per second, sustained
- Each child holds 40–120 MB RSS; the main process footprint peaked at 597 MB
2. Stack evidence: the spawns are synchronous
sample of the main process (pid 80696, 12 s, 8814 samples/thread) resolves the spawn path to Node's synchronous runner:
node::SyncProcessRunner::Spawn(v8::FunctionCallbackInfo<v8::Value> const&) (in Codex Framework) + 640
uv_spawn (in Codex Framework) + 2732
posix_spawn (in libsystem_kernel.dylib) + 496
__posix_spawn (in libsystem_kernel.dylib) + 0
SyncProcessRunner is child_process.spawnSync. Calling it ~5×/s on the Electron main thread blocks the event loop, which is why the whole UI — and, through it, my remote input — stops responding.
Supporting hotspots in the same sample: heavy v8::ArrayBuffer::New churn and node::IsolateData::CreateIsolateData / node::worker::MessagePort::New, consistent with each spawn tearing down and rebuilding worker state.
3. Log fingerprint: IPC router re-election storm
Each spawned client re-registers over IPC and re-runs router election. Comparing the last pre-update session against the post-update sessions in ~/Library/Logs/com.openai.codex/:
| session | app version | uptime | [IpcRouter] I am the router | log files written |
|---|---|---|---|---|
| pid 93935 | pre-update | 10 h 56 min | 0 | 2 |
| pid 83373 | 26.810.41047 | 2 min | 158 | 65 |
| pid 89094 | 26.810.41047 | 2 min | 171 | 73 |
| pid 58173 | 26.810.41047 | 4 min 30 s | 296 | 127 |
The three short sessions are short only because I force-quit them. [IpcRouter] I am the router does not appear even once in the 2,320-line pre-update log covering nearly 11 hours; it appears 158–296 times per 2–4 minutes afterwards.
The app also opens a new log file per spawn (…-t0-… through …-t126-…). Pre-update sessions wrote exactly 2 log files. Post-update sessions wrote 65–127, nearly all zero-byte.
Broadcast storms accompany this — up to 45 log lines in a single second, dominated by:
warning [IpcClient] Received broadcast but no handler is configured method=client-status-changed
Sessions end with the router's socket breaking:
warning [IpcRouter] Socket error errorCode=EPIPE errorMessage="write EPIPE"
at Tse.broadcastClientStatus (…/app.asar/.vite/build/src-BlUt09P1.js:1032:7497)
at Tse.unregisterClient (…/app.asar/.vite/build/src-BlUt09P1.js:1032:6594)
4. Possible trigger (hypothesis, not proven)
The bundled plugin app-server was not refreshed by the update. The installed copy is still the one written by the previous version:
| file | size | sha256 (first 16) | mtime |
|---|---|---|---|
| /Applications/ChatGPT.app/Contents/Resources/codex | 219,666,000 | 7a26b07855ef9119 | 2026-08-14 17:04 |
| ~/.codex/plugins/.plugin-appserver/codex | 218,437,552 | 04ddea2f332bd524 | 2026-08-11 17:58 |
| /Applications/ChatGPT.app/Contents/Resources/codex-code-mode-host | 51,495,456 | 206000a48fbe9d2f | 2026-08-14 17:04 |
| ~/.codex/plugins/.plugin-appserver/codex-code-mode-host | 49,992,576 | 75575bbeae891d4e | 2026-08-11 17:58 |
Both installed copies are stale and hash-mismatched against the bundle, so the file-equivalence check in chrome-plugin-app-server-runtime (the XK sha256 helper identified in #38547) can never succeed. A reconcile that re-checks and re-launches on every failure would produce exactly this unbounded respawn loop.
I want to be explicit that this part is a hypothesis: on macOS bundled_plugins_reconcile_started only appears 2–3 times per session in the logs, so I have not proven the reconcile path is the caller of the spawnSync loop. The measured facts are the spawn rate, the synchronous stack, and the router storm.
What steps can reproduce the bug?
- On macOS 26.5.2 (Apple Silicon), let the Codex app auto-update to
26.810.41047from a26.803.xbuild. - Launch the app. Do not open a conversation, the in-app Browser, or start any task.
- Within ~10 s, run
ps -Ao pid,pcpu,comm | grep 'ChatGPT.app/Contents/Resources/codex'repeatedly and observe the PIDs turning over completely every couple of seconds. - Observe the UI stop responding and system-wide input latency.
- Quit the app — responsiveness returns immediately.
Reproduced on 3 of 3 launches since the update (19:57, 20:01, 22:44 KST) plus a 4th deliberate reproduction at 23:03 KST for this report. Zero occurrences in the ~11 h pre-update session on the same machine, same day.
What is the expected behavior?
The app should launch and sit idle without repeatedly spawning the plugin app-server, and any app-server launch or file-equivalence check should be asynchronous so it can never block the Electron main thread. A failing equivalence check should back off and surface an error rather than retry unbounded.
Additional information
- Related, same
26.810train, but different platform and different mechanism: #38551 and #38547 (Windows). #38547 identifies the sha256 equivalence check inchrome-plugin-app-server-runtimeas the Windows hot path; on macOS the observable failure is aspawnSyncprocess storm, and the UI freeze is far more severe. - Not a duplicate of #27497 (that one hangs before window creation, tied to
auth.json); here the window opens and then the spawn loop starts. - The
sampleoutput (10.7 MB) and the rawpschurn log are available on request. - Only the
codexapp-server children churn; the Chromium renderer and GPU helpers stay in normal ranges apart from brief spikes.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Closing as a duplicate of #38455 — same build (
26.810.41047, 6570) and the same child-process respawn loop, seen from the freeze side rather than the OOM-crash side. Related: #37311 (sameResources/codexapp-server respawn on an earlier build, surfacing as zombies).I have moved the evidence that was unique to this report into #38455: https://github.com/openai/codex/issues/38455#issuecomment-5294882675 — specifically the
node::SyncProcessRunner::Spawn->uv_spawn->posix_spawnstack showing the spawns are synchronous on the Electron main thread (which explains the system-wide input freeze), the measured churn of 75 unique child PIDs in 14 seconds, and the before/after log comparison across the update.Please track it there.