Repository navigation
Codex Desktop app-server leaks child processes and writes excessive logs after crash/restart #26869
Description
Summary
Codex Desktop on macOS appears to lose track of tool child processes across threads and then writes an excessive amount of local log/session state. The visible result was a Codex crash followed by high disk-write pressure, many stale child processes under codex app-server, syspolicyd launch-validation bursts, and eventually a system state where UI remained visible but launching executables/actions became unreliable until reboot.
I am not attaching raw ~/.codex/logs_2.sqlite or session JSONL files because they contain user prompts, local paths, cwd values, command strings, and private project metadata. The details below are sanitized from local diagnostics.
Environment
- App: Codex Desktop
- App bundle version:
26.602.40724(CFBundleVersion 3593) - Codex Framework:
149.0.7827.54 - Binary under load:
/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled - macOS:
26.3 (25D125) - Hardware: Apple Silicon,
Mac16,11 - SIP enabled
What happened
-
Codex Desktop crashed.
- Crash report:
Codex-2026-06-07-014424.ips - Exception:
EXC_BREAKPOINT / SIGTRAP - Faulting thread: main
CrBrowserMainthread - Follow-on renderer abort:
Codex (Renderer)-2026-06-07-014456.ips
- Crash report:
-
After restart/reboot, Codex app-server generated repeated macOS resource diagnostics for disk writes:
codex_2026-06-07-021428_[host-redacted].diag- Event:
disk writes - Writes: about
2147 MBover74s - Heaviest stack ended in
pwrite
- Event:
codex_2026-06-07-022252_[host-redacted].diag- Event:
disk writes - Writes: about
8589 MBover505s - Heaviest stack ended in
pwrite
- Event:
-
Active
codex app-serverhad many long-lived child processes from multiple completed/interrupted tool calls.- Examples of child process types observed under the app-server PID:
rgprocesses/bin/zsh -lc ...shells- Python worker processes
- multiple
node_replprocesses
- Some were tiny/sleeping but persisted for minutes to tens of minutes.
- Examples of child process types observed under the app-server PID:
-
Codex's process registry did not match the actual OS process state.
~/.codex/process_manager/chat_processes.jsoncontained about187records.- About
107records hadosPid: null. - None of the non-null registered
osPidvalues matched currently live OS PIDs at the time of inspection. - The real
codex app-serverstill had live children not represented accurately by that registry.
-
Local Codex log state was very large and actively being written.
~/.codex/logs_2.sqlite: about1.6 GB~/.codex/logs_2.sqlite-wal: about39 MB~/.codextotal: about3.9 GB~/.codex/archived_sessions: about1.7 GB~/.codex/sessions: about264 MB- SQLite log DB contained about
535krows, including about252k TRACErows and about208k INFOrows. - Top log targets included websocket/SSE/otel logging paths, e.g.
codex_api::endpoint::responses_websocket,codex_otel.log_only, andcodex_otel.trace_safe.
-
macOS
syspolicydlogged launch-validation bursts during the incident.- Repeated messages included
dispatch_mig_server returned 268435459and validation-category warnings for rapidly changing PIDs. - This correlated with many command-line children being spawned by Codex.
- User-visible symptom: the desktop looked normal, but executable launches/actions stopped working until reboot.
- Repeated messages included
Expected behavior
- Completed/interrupted tool calls should be reaped reliably.
- Process manager state should match live OS children or cleanly mark completed processes.
- Codex should not keep stale
rg, shell, Python, ornode_replchildren alive after turns are complete. - Local log/session writes should be bounded enough not to trigger macOS disk-write resource diagnostics during normal Desktop use.
- A Codex crash/restart should not leave the app-server in a state that causes system-wide launch/security pressure.
Actual behavior
- Codex app-server retained many child processes from multiple threads.
- Process registry became stale/inaccurate.
- Codex wrote gigabytes of file-backed state within minutes, triggering macOS diagnostics.
- macOS launch validation (
syspolicyd) was hammered by repeated process launches. - The system eventually required reboot because actions/executables stopped working reliably.
Privacy note
I intentionally did not include raw .sqlite, .jsonl, crash report bodies, cwd values, local usernames, hostnames, or command strings that reveal private project names. I can provide raw diagnostics through a private support channel if needed.
Activity
github-actions commentedon Jun 7, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
andersaamodt commentedon Jun 7, 2026
Additional recurrence: this happened a third time on 2026-06-07 after another restart. Post-restart checks again did not point to memory pressure: no swap/compressor pressure and the internal SSD reported SMART Verified with about 60 GiB free. The recurring signal remains launch/process pressure around Codex Desktop: very large syspolicyd validation bursts during/after restart, Codex app-server validation warnings, prior Codex CLI diagnostic reports showing multi-GB disk writes in minutes, and stale process-manager records not matching live OS PIDs. I installed a local low-overhead guard to capture future recurrence metrics without attaching raw logs. Raw local logs still appear privacy-sensitive and are not being shared publicly.
andersaamodt commentedon Jun 7, 2026
Additional evidence from another recurrence on 2026-06-07 around 03:14 PDT: a local guard captured 7 Codex app-server processes and 14 direct children shortly before the restart, plus a fresh Codex diagnostic.
/Library/Logs/DiagnosticReports/codex_2026-06-07-031212_*.diagreports Codex PID 18723 dirtied 2147.48 MB over 254 seconds, with the heaviest stack inpwrite. A 10-second unified-log slice from 03:10:00-03:10:10 contained 3166syspolicyddispatch_mig_server returnedentries and 3168 validation-category-policy entries for rapidly changing PIDs. Shutdown stall collection at 03:14 captured Codexbrowser_crashpad_handlerprocesses, consistent with Codex crashing/restarting during the degraded state. Firefox appeared to hang/crash from the user's perspective, but no fresh Firefox diagnostic report was produced after 03:10, so it looks like collateral launch/system degradation rather than an independent Firefox crash. Raw logs are still not being attached because they contain local/private context.andersaamodt commentedon Jun 8, 2026
Additional evidence from a macOS launch/input freeze investigation (sanitized, no prompt/log payloads):
python3under~/.cache/codex-runtimes/...with a tiny RSS footprint and its stack entirely at_dyld_start.launchctl submitjob running a copied Codexnodebinary stayed in launch/running state instead of exiting immediately. Apple-signed system binaries like/usr/bin/trueand/bin/mkdirstill launched quickly. This points to macOS syspolicy/dyld/provenance assessment under load, not a Python/Node script bug.syspolicydwas hot for long periods and the system accumulated many tiny pre-main or zombie children. Codex app-server was a major amplifier: it had dozens of direct child processes (rg,node_repl, bundled runtime Python/Node, Computer Use helper) stuck with very small RSS. Firefox also accumulated plugin-container zombies.rg. Only a few remembered PIDs were live, so this did not look like a simple relaunch queue, but it is a strong signal that Codex should prune/reconcile stale tool-process state and avoid child-launch storms after reboot or after launch failures.syspolicydreturned near idle and Codex/Homebrew Node launch latency returned to ~0.05s in quiet samples.Codex-specific recommendation: add backpressure/timeouts around app-server child launches on macOS when children remain tiny and stuck at
_dyld_start; aggressively reap/kill and mark failed rather than continuing to spawn; prune stale~/.codex/process_manager/chat_processes.jsonrecords; and avoid repeated Computer Use/helper launches while syspolicy validation is saturated. Codex was not the only root cause in this incident, but it amplified the system-wide launch wedge enough that the whole GUI/input session became unrecoverable without a reboot.andersaamodt commentedon Jun 8, 2026
Follow-up evidence from a later recurrence on macOS (2026-06-07 around 22:24-22:25 PT), sanitized to avoid raw prompts/payloads:
syspolicydrepeatedly sat around ~51-53% CPU while Codex-launched child processes remained at extremely low RSS (typically 32 KB), consistent with being stuck pre-main / before interpreter startup.node ... prettier --check ...,rg ..., and short shell helpers. The parent of the live stuck children was/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled.com.apple.Gatekeeper.PolicyViolationtelemetry fromsyspolicyd,com.apple.syspolicy.execmessages withdispatch_mig_server returned 268435459, and messages of the formPID ... violates validation category policy. This will likely result in a block in the future. macOS privacy redacted the executable path in the log, but simultaneouspsoutput tied the active low-RSS launch queue to Codex app-server descendants.This points to Codex Desktop needing backpressure/reuse/throttling around child process launches and/or explicit detection of macOS launch-assessment saturation (
syspolicyd/syspolicy.exec) so it stops scheduling more non-system executable launches while the OS launch path is wedged. Raw command payloads are intentionally omitted because they can include user prompt text and local paths.andersaamodt commentedon Jun 8, 2026
Cross-linking related reports that look like the same or adjacent failure domain. I’m not claiming they all have one root cause, but they point at the same macOS launch-assessment / signing / helper-process pressure area:
syspolicyd/trustdCPU and memory runaway #25719 — Codex Desktop for macOS repeatedly triggerssyspolicyd/trustdCPU and memory runaway. This looks closest to the system-wide app-launch failure pattern reported here.syspolicyd/ XProtect scanning storms when spawned repeatedly. This is relevant because the observed failure here also correlates with repeated non-system executable launches andsyspolicydsaturation.launchd. Related because leaked or repeated helpers increase the launch/assessment/process pressure that can make the macOS failure mode much worse.SkyComputerUseClientSIGKILL / code-signature invalid when launched outside the expected app process tree. Relevant because this report capturedSkyComputerUseClient/Computer Use helper launches in the same incident family, and signing/launch constraints appear to be involved.The common engineering hypothesis from this report plus those threads: Codex Desktop should apply backpressure/reuse/throttling around spawned helpers and tool-server processes, and should detect when macOS launch assessment (
syspolicyd/syspolicy.exec/ trust validation) is saturated before scheduling more non-system executable launches. It would also help to verify notarization/signing/caching behavior for all shipped helper binaries, especially Computer Use /SkyComputerUseClientand CLI/runtime binaries that may be spawned repeatedly.andersaamodt commentedon Jun 8, 2026
Follow-up with a more specific recovery experiment from the 2026-06-08 recurrence, again sanitized to avoid prompt text or local command payloads:
/usr/bin/true,/bin/ls) launched immediately, while a Codex-bundled helper launch (/Applications/Codex.app/Contents/Resources/node_repl --version) hung. That narrowed the failure to non-system executable launch assessment rather than global CPU, disk, or shell failure.rg, Playwright/Chromium helpers, and site-status/build helpers launched through active Codex work.syspolicydCPU dropped from roughly 56% to under 1%, and the count of Codex low-RSS stuck children fell to zero. No reboot and no Codex quit was needed for that observed drain.This is stronger evidence that Codex Desktop needs a macOS launch-assessment backpressure mechanism, not only orphan cleanup after the fact: if spawned children remain tiny/pre-main or syspolicy validation is hot, Codex should stop scheduling more non-system executable launches, reuse existing helper processes where possible, and aggressively fail/reap the stuck child jobs instead of continuing to fan out.
andersaamodt commentedon Jun 11, 2026
Additional live incident evidence from 2026-06-10 ~20:00 PDT:
syspolicydwas repeatedly at ~53-67% CPU while many newly launched non-system helpers sat at ~32 KB RSS, apparently pre-main / blocked in launch assessment.rg, node/node_repl, Computer Use completion helpers), Firefox plugin-container launches, and a local Headquarters deployment automation fanout (auto-template, publish-status/site-status, and auto-push/publish helpers).syspolicydwhile fanout continued also immediately re-saturated it.syspolicyd. After that:syspolicydreturned to 0.0% CPU and the low-RSS stuck queue went to zero.sampleof the hotsyspolicydprocess showed the active path undersyspolicyd.executions.migin Security.framework code-signing verification, especiallySecCodeCopySigningInformation,Security::CodeSigning::SecStaticCode::signingInformation,validateDirectory,CMSDecoderCopySignerStatus, and timestamp/cert parsing (decodeTimeStampTokenWithPolicy). This supports the diagnosis that the stall is launch/code-signing assessment saturation, not DNS/network/SSD/memory pressure.Local mitigation added on my side: I throttled one local app's background publish/status fanout and added a macOS launch-pressure guard so it defers passive automation when
syspolicydCPU or 32 KB launch-stall counts are high. That helps reduce one producer, but Codex still appears able to create the same pressure via multiple active/background threads and completion/helper launches.jiansongy commentedon Jun 30, 2026
Independent reproduction on Intel macOS — same disk-write/log signature, escalating to a full WindowServer watchdog kill (whole-screen freeze)
Corroborating this on different hardware and a much newer build. Same
2147 MB … pwritedisk-write signature and TRACE-dominatedlogs_2.sqlite, but here it escalated past "launches stall" to a WindowServeruserspace_watchdog_timeout— the entire screen froze, twice in one day.Environment
26.623.70822(CFBundleVersion4559) — newer than the3593above, so the behavior persists in current builds149.0.7827.197; binary under load…/Codex.app/Contents/Resources/codex app-server --analytics-default-enabledMacBookPro16,2, Intel x86_64, 8 logical CPUs, 16 GB — the reports here so far are Apple Silicon; this widens scope to Intel26.5.1 (25F80), SIP enabledWhat macOS recorded
codex_<ts>.diag—Event: disk writes, 2147.48 MB dirtied over 8825 s (~243 KB/s, ~10× the limit). Heaviest stack is SQLite WAL churn:sqlite3_exec → sqlite3_step → sqlite3_wal_checkpoint_v2 → pwrite(viasqlx_sqlite).~/.codex/logs_2.sqlitewas 301 MB / 80,685 rows, 71% TRACE (57k TRACE / 14k INFO / 8k DEBUG vs 1.2k WARN / 20 ERROR) over a 10-day span — overwhelmingly trace-logging write amplification, matching thecodex_otel.trace_safe/*.log_onlytargets noted above.codex app-serverinstances at freeze time, one orphaned tolaunchd(PPID 1) since ~7 h earlier, never reaped, still holdinglogs_2.sqliteopen and writing. ~38 Codex-owned processes / ~1.3 GB RSS incl. accumulatedcua_node/node_repl+mcp-serverchildren (matches Codex for macOS accumulates Computer Use / MCP helper processes and unreaped zombie children, causing HID lag and WindowServer/TCC stalls #25744).userspace_watchdog_timeout→ whole-screen freeze (the new/worse symptom). The spindump shows WindowServer was not CPU-spinning: its main thread used 0.2 s CPU over the 5.57 s watchdog window and was blocked inmach_msgthe whole time (SkyLight → … → mach_msg_trap),CoreDisplaylikewise blocked. Reason:WindowServer returned not alive … Display … not ready … Surface Use Counts: 2(1) 10(3) 11(1). It was starved, not buggy — it could not get a timely reply while the run queue was saturated. In the same stackshot the top CPU consumers weresyspolicyd(3.0 s, incom.apple.security.syspolicy.yara/ XProtect) andtrustd(1.2 s) — consistent with Codex Desktop for macOS repeatedly triggerssyspolicyd/trustdCPU and memory runaway #25719, driven by the constant new-process launches. Load average ≈ 470, ≈ 105 MB free RAM at that instant.So the separately-filed symptoms look like one chain on a memory-constrained Mac: app-server child/log leak (this issue) + CUA/MCP accumulation (#25744) saturate CPU/RAM/disk →
syspolicyd/trustdspike (#25719) → WindowServer misses its watchdog deadline → it gets killed → full-screen freeze.Mitigations that worked here (until the next session): kill the orphaned app-server; prune old
logsrows +VACUUM(301 → 110 MB); restart Codex (collapses 38 → 14 processes, 2 → 1 app-server). A user-facing toggle to disable--analytics-default-enabledor a size cap onlogs_2.sqlitewould remove the disk-write driver. Redacted.spin/.diagheaders available on request.Veneyo commentedon Aug 11, 2026
Linux confirmation: stale
node_replhelpers trigger an inotify-capacity warningI observed a closely related child-process lifecycle symptom on Linux. In this case, accumulated Codex helpers caused KDE to report exhausted inotify instance capacity.
Environment
7.1.5-201.fc44.x86_646.7.3kde-inotify-survey26.04.326.803.81509No usernames, hostnames, local paths, PIDs, project names, task contents, command arguments, or raw logs are included below.
Observed state
System limits:
fs.inotify.max_user_instances = 128fs.inotify.max_user_watches = 268688KDE reported:
A measurement shortly afterward found 399 per-process inotify descriptor references across the user session. At least 342 were associated with the ChatGPT/Codex process tree:
node_replprocesses: 216 referencesnodeprocesses: 102 referencesAll 36
node_replprocesses had the same Codex parent and had accumulated over roughly 12 minutes.The 399 count represents descriptor references, not necessarily 399 unique kernel inotify instances. The Codex parent held eight inotify descriptors; two sampled
node_replchildren each held the same subset of six descriptor numbers as the parent. That suggests descriptor inheritance, potentially from descriptors not marked close-on-exec. It may also amplify KDE's percentage calculation, but it does not explain away the accumulation of 36 helper processes.Restart result
After fully quitting and relaunching the desktop app:
node_replprocesses: 36 → 1nodeprocesses: 17 → 1Additional normal tool use after the restart left only one
node_repl/nodepair, so I have not yet reproduced the accumulation deterministically. This suggests the app-server or process manager may first need to enter a degraded state.Impact and suggested investigation
This produces a system-level warning and risks preventing unrelated applications from creating file monitors. Raising
fs.inotify.max_user_instanceswould only mask the lifecycle issue.It may be useful to check:
node_repl/Node helpers are reliably reaped or reused;FD_CLOEXEC/O_CLOEXEC;This appears consistent with the stale child-process behavior described in this issue, with Linux inotify pressure as an additional user-visible consequence.