codex app-server saturates macOS syspolicyd, hanging the terminal
What version of the Codex App are you using (From “About Codex” dialog)?
26.422.30944 (2080)
What subscription do you have?
Pro ($200/mo)
What platform is your computer?
Darwin 25.2.0 arm64 arm
What issue are you seeing?
On macOS, the codex app-server process fork-execs the bundled node helper (Codex.app/Contents/Resources/node_repl) at ~250 per second while working with six subagents. Because that helper does not pass macOS's expected validation category, every exec triggers a full Gatekeeper crypto check. Within a few hours of running Codex, syspolicyd saturates a CPU core, every new shell command stalls for several seconds (zsh interactive startup goes from sub-second to 4+ minutes), and Apple emits the warning "This will likely result in a block in the future."
Evidence:
2026-04-27 15:27:45.203127-0400 syspolicyd: [com.apple.syspolicy.exec:default] <private> with PID 29375 violates validation category policy. This will likely result in a block in the future
2026-04-27 15:27:45.207037-0400 syspolicyd: [com.apple.syspolicy.exec:default] <private> with PID 29376 violates validation category policy. This will likely result in a block in the future
2026-04-27 15:27:45.210908-0400 syspolicyd: [com.apple.syspolicy.exec:default] <private> with PID 29377 violates validation category policy. This will likely result in a block in the future
... (sequential PIDs continue at ~250/sec)
$ ps -p 53907 -o pid,ppid,etime,command
PID PPID ELAPSED COMMAND
53907 52783 01:22:43 /Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled
$ # racing capture of children:
30413 53907 node
Quitting Codex immediately ends the violation stream; reopening Codex restarts it. Killing only the codex app-server PID stops the issue until Codex respawns it.
Why this matters beyond performance: Apple's log message ("This will likely result in a block in the future") indicates a future macOS update will outright block these execs, breaking Codex on macOS for all users.
Suggested fix: Either (a) ship a properly Developer-ID-signed, notarized, hardened-runtime helper binary at Contents/Resources/node_repl, or (b) replace fork-exec of the helper with an in-process or persistent-worker pattern so the validation cost is paid once instead of per-call.
What steps can reproduce the bug?
Reproduction:
- macOS [version], Codex [version].
- Launch Codex, work for multiple hours, especially with multiple subagents on a project.
- In any terminal: time zsh -i -c exit — observe wall time of multiple minutes.
- ps aux | sort -k3 -rn | head — syspolicyd ~80% CPU, trustd ~20% CPU.
What is the expected behavior?
Running Codex should not noticeably impact system-wide performance. Specifically:
- The bundled node_repl helper should be a properly Developer-ID-signed, notarized, hardened-runtime binary so that macOS's syspolicyd can cache its validation result on first execution and skip full crypto verification on subsequent execs.
- syspolicyd and trustd CPU usage should remain at idle baseline (typically <5%) while Codex is running, regardless of how long it has been open.
- macOS should not log "violates validation category policy. This will likely result in a block in the future" for any binary Codex ships or invokes.
- Unrelated terminal sessions and shell commands should remain responsive — time zsh -i -c exit should complete in well under a second, the same as before Codex was launched.
Additional information
I didn't attempt to replicate this with the codex CLI, but using OpenCode, having GPT-5.5 Fast do work is blazing fast compared to within the Codex desktop app (in the realm of ~20x faster for me, a code review went from taking 40 minutes+ to 2-3 minutes)
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks for reporting this and for sharing your analysis.
node_replis intended to be a persistent MCP-style helper/kernel, so the expected process count should be closer to “one per active runtime context that needs it,” possibly multiplied by subagents, not hundreds of execs per second.Does your use case involve the rapid spawning and termination of subagents, or are you spawning six subagents and then using them for an extended time?
A rate of ~250 execs/sec suggests a restart/reconnect/crash loop around
node_replor its inner bundlednodeprocess, rather than normal per-tool-call behavior. Do you see any evidence of that?I'm spawning 6 agents in parallel that are somewhat long running (I have some set of acceptance criteria, for my current ticket 43 bullet points, have 5 agents iterating through the list of acceptance criteria to verify it is being met, and one that does a general code review)
Do you have any advice on how I can find said evidence? I'd love to help get this solved as I prefer the Codex desktop application to OpenCode, which I'm using now as it doesn't cause these issues for me.
With Codex, going through a list of acceptance criteria would take 45+ minutes with 5 agents + 1 agent doing a general code review, through OpenCode a full round of testing/analysis is around 3-4 minutes, both using GPT-5.5 Fast (xhigh).
Update — diagnosis was wrong on my end. The rapid spawning isn't node_repl. After capturing full argv with ps -o args=, the actual binary is:
node /Users/chris/.nvm/versions/node/v24.4.0/lib/node_modules/oh-my-codex/dist/scripts/codex-native-hook.js
So this is oh-my-codex, a third-party npm package, registering itself as a Codex "native hook" and being invoked at ~250/sec — each call fork-execs a fresh Node process rather than running through a persistent helper. Apologies for the noise; the user-facing macOS symptom (syspolicyd saturation) was real, but the offending code is third-party.
One feedback item that may still be useful for Codex: the native-hook integration mechanism let a third-party package fork-exec at ~250/sec for hours without any rate limit, lifecycle warning, or visible diagnostic to me. If there's a way to log/throttle hook spawn rates, or to require hooks to declare a persistent-worker mode, that would help users avoid this class of issue.