macOS: Codex Desktop/app-server appears to exhaust syspolicyd, causing spctl “Too many open files” globally

Open 💬 15 comments Opened Jun 11, 2026 by sysoft
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

On macOS 26.2, after running Codex Desktop for a while, Gatekeeper/SystemPolicy enters a broken state where spctl returns Too many open files for every assessed path, including /bin/ls, /tmp, newly-created text files, zip files, DMGs, and unrelated apps. Finder then reports unrelated apps/DMGs as "damaged" and suggests moving them to Trash.

This looks related to existing syspolicyd/Gatekeeper issues, but I am filing a new issue because it reproduces on Codex Desktop 26.608.12217 and local diagnostics point specifically at /Applications/Codex.app/Contents/Resources/codex / app-server / temporary codex-execve-wrapper paths rather than a single downloaded app.

Related issues: openai/codex#25243, openai/codex#25882, openai/codex#26869.

Environment

  • macOS: 26.2, build 25C56
  • Architecture: Apple Silicon / arm64e
  • Hardware model from diagnostics: MacBookPro18,2
  • Codex Desktop: 26.608.12217 (CFBundleVersion 3722)
  • Codex binary being diagnosed: /Applications/Codex.app/Contents/Resources/codex
  • SIP: enabled
  • Gatekeeper assessments: enabled

User-visible symptoms

  • Freshly downloaded DMGs show the macOS dialog: "<file>.dmg" is damaged and can't be opened. You should move it to the Trash.
  • Existing apps show the same kind of "damaged" dialog.
  • The affected files are not actually corrupt. Example: a Royal TSX DMG verified successfully with hdiutil verify, and codesign reported a valid Developer ID signature and stapled notarization ticket.

Local diagnostics

spctl fails globally once the system is in this state:

$ spctl --assess --type execute --verbose=4 /bin/ls
/bin/ls: Too many open files

$ spctl --assess --type open --context context:primary-signature --verbose=4 ~/Downloads/royaltsx_5.0.4.1000.dmg
~/Downloads/royaltsx_5.0.4.1000.dmg: Too many open files

$ spctl --assess --type open --context context:primary-signature --verbose=4 /tmp/plain.txt
/tmp/plain.txt: Too many open files

This is not global file descriptor exhaustion:

$ sysctl kern.num_files kern.maxfiles kern.maxfilesperproc
kern.num_files: 14048
kern.maxfiles: 491520
kern.maxfilesperproc: 245760

$ ulimit -n
1048575

syspolicyd looked unhealthy when the issue occurred:

$ top -l 1 -pid <syspolicyd-pid> -stats pid,command,cpu,mem,rsize,vsize,threads,time
PID  COMMAND    %CPU MEM  MEM  VSIZE #TH TIME
530  syspolicyd 0.0  801M 801M N/A   29  02:24:31

System diagnostics also recorded syspolicyd doing sustained SQLite/WAL writes:

Command:          syspolicyd
Path:             /usr/libexec/syspolicyd
Event:            disk writes
Writes:           2147.49 MB of file backed memory dirtied over 25569 seconds
Heaviest stack:   sqlite3_step -> sqlite3VdbeExec -> pagerWalFrames -> unixWrite -> guarded_pwrite_np

Evidence pointing at Codex

There are repeated macOS diagnostic reports for the Codex binary itself:

Command:          codex
Path:             /Applications/Codex.app/Contents/Resources/codex
Codesigning ID:   codex
Team ID:          2DC432GLL2
Event:            disk writes
Writes:           2147.49 MB over 1667 seconds
Writes:           8589.93 MB over 3518 seconds
Writes:           8589.94 MB over 6479 seconds
Heaviest stack:   ... -> pwrite

Local Codex state also contains many temporary arg0 wrapper entries:

$ find ~/.codex/tmp/arg0 -maxdepth 2 -name codex-execve-wrapper -print | wc -l
15

$ stat -f '%Sm %N -> %Y' -t '%Y-%m-%d %H:%M:%S' ~/.codex/tmp/arg0/codex-arg0*/codex-execve-wrapper
...
2026-06-12 01:54:51 ~/.codex/tmp/arg0/codex-arg0IgknVX/codex-execve-wrapper -> /Applications/Codex.app/Contents/Resources/codex
2026-06-12 01:55:18 ~/.codex/tmp/arg0/codex-arg0wc32Ni/codex-execve-wrapper -> <VS Code extension>/bin/macos-aarch64/codex
2026-06-12 01:57:57 ~/.codex/tmp/arg0/codex-arg0Tmh6By/codex-execve-wrapper -> <npm global codex>/vendor/aarch64-apple-darwin/codex/codex

The wrapper is a symlink to a signed Codex binary:

$ codesign -dv --verbose=2 ~/.codex/tmp/arg0/<one-dir>/codex-execve-wrapper
Executable=/Applications/Codex.app/Contents/Resources/codex
Identifier=codex
Authority=Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2)
TeamIdentifier=2DC432GLL2
Runtime Version=15.5.0

Codex Desktop logs also show very active app-server state around this time, including repeated AppServerConnection entries and repeated warnings like:

[electron-message-handler] No owner repo found for remote task taskId=...

The currently observed process tree includes multiple Codex app-server / node_repl processes. On this machine I did not find evidence that Locked Computer Use was installed as a SecurityAgentPlugin, and SkyComputerUseService was not running during the later inspection, so the strongest local signal is app-server / shell-tool execution / codex-execve-wrapper, not Computer Use specifically.

Expected behavior

Codex Desktop/app-server/tool execution should not drive syspolicyd into a state where spctl globally fails with Too many open files, and unrelated apps/DMGs should not be reported as damaged.

Actual behavior

After Codex has been running for some time, spctl fails for all files with Too many open files, and Finder/Gatekeeper reports unrelated apps and DMGs as damaged.

Workarounds tried / notes

  • sudo launchctl kickstart -k system/com.apple.security.syspolicy does not work with SIP enabled:
Could not kickstart service "com.apple.security.syspolicy": 150: Operation not permitted while System Integrity Protection is engaged
  • Rebooting clears the state, but the problem recurs.
  • Quitting Codex Desktop and killing syspolicyd/trustd is likely less disruptive than rebooting, but the root cause appears to be Codex repeatedly triggering the condition.

Ask

Could the team investigate whether Codex Desktop/app-server or the temporary ~/.codex/tmp/arg0/.../codex-execve-wrapper mechanism can repeatedly trigger Gatekeeper/SystemPolicy assessment or excessive SystemPolicy DB writes on macOS 26.2?

If there is a narrower diagnostic flag/logging command for app-server/tool execution on macOS, I can collect that output.

View original on GitHub ↗

15 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #26341
  • #26117
  • #27136
  • #26869

Powered by Codex Action

omarpinarecords · 2 months ago

I submitted related in-app feedback with Feedback ID: 019ed2cb-eea6-7851-be4d-8be66a992d92.

My local checks on macOS 26.5.1 build 25F80 showed the same Gatekeeper/SystemPolicy failure family: spctl --assess --type execute --verbose=4 /bin/ls failed with internal error in Code Signing subsystem. The same error also occurred when assessing Codex, Cursor, a normal local Markdown file, and /opt/homebrew/bin/openai.

The visible user-facing symptom was macOS showing: "openai" is damaged and can’t be opened. You should move it to the Trash. The Homebrew OpenAI CLI still ran from Terminal (openai version 1.2.0) and codesign showed it was signed by Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2), so this did not look like a corrupted local file. It looked like the same broader SystemPolicy/Gatekeeper broken state described in this issue.

nabong · 2 months ago

Same failure family here on macOS 26.2 (build 25C56), Codex Desktop 26.611.62324, Apple Silicon. I want to add a concrete, fixable root cause that I was able to verify on my machine, because in my case the trigger was not a respawn storm — it was the default launchctl file-descriptor limit being far too low for Codex's bundle size.

Root cause: launchctl limit maxfiles defaults to 256

syspolicyd is launched by launchd and inherits the global launchctl maxfiles soft limit, which on a stock install is just 256:

$ launchctl limit maxfiles
	maxfiles    256            unlimited

Codex.app ships a very large bundle. On my install it has 7898 Sealed Resources, dominated by an embedded Node runtime:

$ codesign -dvv /Applications/Codex.app 2>&1 | grep "Sealed Resources"
Sealed Resources version=2 rules=13 files=7898

# where those files come from:
6200  Contents/Resources/cua_node        # full Node.js dist incl. include/*.h headers + bundled npm
 934  Contents/Resources/plugins
 655  Contents/Resources/app.asar.unpacked

When Gatekeeper assesses this bundle, syspolicyd opens a large number of files at once and blows past the 256 soft limit, after which every assessment fails with EMFILE globally — exactly the symptoms in this thread (/bin/ls, DMGs, unrelated apps all reported "damaged" / Too many open files). Note the system file table is nowhere near full when this happens:

$ sysctl kern.num_files kern.maxfiles
kern.num_files: 13102
kern.maxfiles: 184320      # ~7% used

So it is not global FD exhaustion — it's the per-daemon 256 soft cap being too small for a 7898-file bundle. codesign --verify passes (it doesn't fan out across all sealed files the same way), which is why the bundle is valid yet spctl fails.

Fix that worked for me (and held)

Raising the launchctl limit and restarting syspolicyd resolved it completely in my case:

$ sudo launchctl limit maxfiles 65536 524288
$ sudo killall -HUP syspolicyd

After this, 5 consecutive spctl -a /Applications/Codex.app runs all returned accepted, Codex and VS Code launched normally, and syspolicyd CPU dropped from ~59% back to ~1%. Crucially, it stayed fixed after launching Codex — re-assessing repeatedly kept passing.

To make it survive reboot I added a LaunchDaemon:

<!-- /Library/LaunchDaemons/limit.maxfiles.plist -->
<plist version="1.0"><dict>
  <key>Label</key><string>limit.maxfiles</string>
  <key>ProgramArguments</key>
  <array>
    <string>launchctl</string><string>limit</string><string>maxfiles</string>
    <string>65536</string><string>524288</string>
  </array>
  <key>RunAtLoad</key><true/>
</dict></plist>

Caveat

In my case Codex's main process was stable (single PID, no respawn loop), so raising maxfiles was a genuine fix. For the reports here where Codex is also doing a posix_spawn storm of its own GUI binary (#26869 and others), raising maxfiles will only delay exhaustion — that part still needs an app-side backoff/retry cap.

Suggestions for the Codex team

  1. Shrink the bundle. cua_node ships ~2755 .h headers and a full bundled npm (with its own node_modules) that aren't needed at runtime. Trimming dev artifacts / archiving JS into asar would drop the sealed-resource count dramatically and ease the pressure on syspolicyd.
  2. Consider documenting the launchctl limit maxfiles workaround for affected macOS users until the bundle is slimmed down.

Environment for the record: macOS 26.2 (25C56), Codex 26.611.62324, Apple Silicon, SIP enabled, Gatekeeper enabled.

nabong · 2 months ago

Update (2026-06-19): My earlier claim that raising maxfiles to 65536 "fixed it and held" was premature. While it significantly reduces the frequency (from minutes to hours), the underlying issue — codex app-server continuously spawning the GUI binary and triggering Gatekeeper assessments without backoff — still causes intermittent syspolicyd CPU churn (saw 159%!) and transient FD spikes. When saturated, syspolicyd fails globally again.

Root cause confirmed (matches #16767, #26869): codex app-server's unbounded posix_spawn + no-cache assessments drive syspolicyd into CPU runaway. Raising maxfiles helps but doesn't fix the app-side bug.

Practical mitigation: Quit Codex Desktop (Cmd+Q) when not in use. The CLI (codex exec) doesn't run app-server persistently. For those keeping it open, I wrote a watchdog that auto-restarts syspolicyd when CPU/RSS spikes: https://github.com/zyzhou9/my-claude-work/tree/master/scripts

Apologies for the earlier overconfidence — this is genuinely a tough one to pin down.

gsusI · 2 months ago

Adding another sanitized data point that appears to match this issue exactly.

Environment

macOS: 26.6 (25G5043d)
Architecture: arm64
SIP: enabled
Gatekeeper: assessments enabled
Codex Desktop: 26.616.31447
Codex CFBundleVersion: 4133
Codex Team ID: 2DC432GLL2

Codex.app itself verifies as signed/notarized:

Executable=/Applications/Codex.app/Contents/MacOS/Codex
Identifier=com.openai.codex
Authority=Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2)
Notarization Ticket=stapled

User-visible impact

Unrelated apps and DMGs started showing macOS "damaged and can't be opened" dialogs. The affected items were not actually corrupt:

  • Official Stremio DMG: hdiutil verify reported checksum ... is VALID.
  • Telegram.app: codesign --verify --deep --strict passed; signed by TELEGRAM MESSENGER LLP (6N38VWS5BX); notarization ticket stapled.
  • Visual Studio Code Insiders: codesign --verify --deep --strict passed; signed by Microsoft Corporation (UBF8T346G9); notarization ticket stapled.

Yet Gatekeeper/SystemPolicy failed with:

spctl: Too many open files

For VS Code Insiders specifically, LaunchServices could spawn/check in the app, then AppleSystemPolicy killed it shortly after:

ApplicationManager: Checked in app : Visual Studio Code - Insiders
ASP: Security policy would not allow process: <pid>, /Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Code - Insiders
CAS notification for appDeath for com.microsoft.VSCodeInsiders

So the downstream failure was not just a stale Finder dialog. macOS policy enforcement actively killed an unrelated signed/notarized app after launch.

syspolicyd / AppleSystemPolicy evidence

The system-wide file table was not close to full:

launchctl limit maxfiles
  maxfiles    256            unlimited

kern.num_files: ~9k-13k
kern.maxfiles: 368640
kern.maxfilesperproc: 184320

Representative unified-log lines:

syspolicyd: UNIX error exception: 24
syspolicyd: Failed to generate SecStaticCode for <private> error: 100024
syspolicyd: not allowed to create a new connection (existing Connection ...)
syspolicyd: nw_socket_initialize_socket Failed to create socket(2,2) [24: Too many open files]
ASP: Security policy would not allow process: <pid>, /Applications/Codex.app/Contents/MacOS/Codex

In one 10-minute sample while Codex Desktop was running, filtered logs counted approximately:

Codex main-executable policy denials: 19,461
code_sign_clone denials: 22
AppleSystemPolicy security denials: 19,410
provenance sandbox failures: 1,350
EMFILE lines: 1

In a later 60-second sample, while the machine was already in the bad state, there were about:

AppleSystemPolicy security denials: 4,157
EMFILE lines: 1

Recovery behavior

  • Reboot had previously restarted syspolicyd, but the issue recurred after Codex Desktop was running again.
  • sudo launchctl kickstart -k system/com.apple.security.syspolicy was blocked by SIP:
Could not kickstart service "com.apple.security.syspolicy": 150: Operation not permitted while System Integrity Protection is engaged
  • Quitting Codex Desktop and rebooting is currently the practical recovery path for this user.
  • Reopening Codex Desktop is expected to retrigger the failure.

Notes

This does not look like corruption of Stremio, Telegram, or VS Code Insiders. It looks like Codex Desktop repeatedly triggering macOS SystemPolicy assessment of its own executable/helpers until syspolicyd enters an EMFILE/broken-state condition, after which unrelated signed/notarized apps and DMGs are rejected or killed.

A useful product-side mitigation would be a safe mode / feature-disable path that avoids high-risk helper/plugin startup, plus bounded retry/backoff around any path that can trigger repeated policy assessment of /Applications/Codex.app/Contents/MacOS/Codex or code_sign_clone/.../Codex.app.bundle/Contents/MacOS/Codex.

hatawong · 2 months ago

I hit a very similar failure mode, but in my case the strongest local signal was the Computer Use / SkyComputerUse runtime rather than only codex-execve-wrapper.

Symptoms

  • Multiple unrelated macOS apps started launching very slowly or failed to launch.
  • Chrome eventually stopped launching normally.
  • Some freshly downloaded DMGs also failed to open.
  • syspolicyd / trustd showed sustained high CPU.
  • spctl returned Too many open files for otherwise valid apps.

Example:

spctl -a -t execute -vvv "/Applications/Google Chrome.app"
# /Applications/Google Chrome.app: Too many open files

After recovery, the same check returned:

/Applications/Google Chrome.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Google LLC (EQHXZ8M8AV)

Important observation

Disabling the Computer Use plugin was not sufficient by itself.

I had:

[plugins."computer-use@openai-bundled"]
enabled = false

[features]
computer_use = false

but Codex Desktop still restored a user-level runtime app under:

~/.codex/computer-use/Codex Computer Use.app

and it could also write back a notify hook pointing to:

~/.codex/computer-use/Codex Computer Use.app/Contents/SharedSupport/SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient

That means Computer Use can still be invoked indirectly through:

notify = [".../SkyComputerUseClient", "turn-ended"]

even when the plugin itself appears disabled.

Workaround that stabilized my machine

This is not a product fix, but it stopped the recurrence locally.

  1. Remove the notify = [...SkyComputerUseClient..., "turn-ended"] line from ~/.codex/config.toml.
  1. Keep Computer Use disabled while leaving browser-related plugins enabled:
[plugins."computer-use@openai-bundled"]
enabled = false

[plugins."browser@openai-bundled"]
enabled = true

[plugins."chrome@openai-bundled"]
enabled = true

[features]
computer_use = false
  1. Kill any existing Computer Use runtime processes:
pkill -TERM -f 'SkyComputerUse|Codex Computer Use|SkyComputerUseClient' 2>/dev/null || true
sleep 2
pkill -KILL -f 'SkyComputerUse|Codex Computer Use|SkyComputerUseClient' 2>/dev/null || true
  1. If Codex Desktop keeps restoring and launching the user-level runtime, block only the user-level Computer Use executables. Do not modify /Applications/Codex.app, since that can break the app signature.
svc="$HOME/.codex/computer-use/Codex Computer Use.app/Contents/MacOS/SkyComputerUseService"
cli="$HOME/.codex/computer-use/Codex Computer Use.app/Contents/SharedSupport/SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient"

for f in "$svc" "$cli"; do
  chflags nouchg "$f" 2>/dev/null || true
  chmod 000 "$f"
  chflags uchg "$f"
done
  1. Reboot macOS. In my case, rebooting was necessary once syspolicyd had already entered the broken state. Trying to restart com.apple.security.syspolicy directly was blocked by SIP.
  1. After reboot, verify:
pgrep -alf 'SkyComputerUse|Codex Computer Use|SkyComputerUseClient' || true
spctl -a -t execute -vvv "/Applications/Google Chrome.app"

Expected:

  • no real SkyComputerUseService / SkyComputerUseClient process
  • no Too many open files
  • spctl returns accepted

Reverting the workaround

If you want to re-enable Computer Use later:

for f in "$svc" "$cli"; do
  chflags nouchg "$f" 2>/dev/null || true
  chmod 755 "$f"
done

Then re-enable Computer Use from Codex settings/config and restart Codex.

Suggested product-side fix

Codex Desktop should probably not auto-install, auto-restore, launch, or write a notify hook for Computer Use when:

  • [features].computer_use = false, or
  • [plugins."computer-use@openai-bundled"].enabled = false

Also, uninstalling/disabling Computer Use should remove or ignore any notify hook that points to SkyComputerUseClient.

The key issue here is that the visible plugin state and the actual user-level Computer Use runtime state can diverge. When they diverge, SkyComputerUseClient may still be invoked and can contribute to the same global Gatekeeper / syspolicyd failure pattern described in this issue.

rodalpho · 2 months ago

This is a huge problem and renders codex app unusable on my machine.

jamguoxiaoqi · 2 months ago

I encountered this syspolicyd problem yesterday on a very fresh version:
Version 26.616.71553 • Released Jun 23, 2026

I tried many ways I can find in all comments from all issues I can found but no one works.
Until I found a stray/corrupted .git folder under one of my codex working directory, which contains multiple repos (but it should not have its own .git).

$ find .
.
./objects
./objects/pack
./objects/pack/tmp_idx_10pAga
./objects/pack/tmp_idx_TqD4PQ

I removed it and everything is fine now.

After open Codex App, syspolicyd will run at ~50% for only couple seconds, not infinitively 150% anymore.
computer use, browsers, etc. are all enabled.

Hope this helps.

rodalpho · 2 months ago

Yes, it was caused by empty .git folders from syncthing on my machine. Codex should handle this gracefully without essentially rendering your OS unusable.

zenghuasheng · 1 month ago

Reproduced this today (2026-07-16) via the ChatGPT macOS app (not the standalone Codex.app), which bundles the same codex app-server. Adding a data point that may help narrow the root cause:

Timeline (sampled every 15s):

  • Before ChatGPT launch: syspolicyd idle at 0-0.3% CPU, no hung processes.
  • Within ~15-20s of launching ChatGPT: syspolicyd CPU jumped to 81.4%, 2 new processes stuck at <=128KB RSS (dyld startup stage).
  • Over the next ~90s: stuck process count grew from 1 to 4, new-process spawn latency increased.
  • A completely unrelated process (brew shellenv invoked by zsh login startup) got stuck for 4.5 minutes at 32KB RSS, blocking Terminal from presenting a shell prompt at all.

New finding - quitting the app is not sufficient:
killall ChatGPT (or quitting normally) only kills the top-level app. The codex app-server process (/Applications/ChatGPT.app/Contents/Resources/codex ... app-server --analytics-default-enabled) gets reparented to launchd (PPID becomes 1) and keeps running and keeps spawning new node_repl children (observed count grow from 2 to 3 with zero user interaction after the app was quit). syspolicyd stayed pegged at ~54% the whole time it was orphaned.

Only after manually kill -9-ing the orphaned app-server PID (and its remaining children) did syspolicyd CPU drop to 0% and system-wide process spawn latency return to normal.

This suggests the fix needs to cover two things: (1) the exec/validation cost per the analysis in #19885, and (2) proper process-group cleanup on app quit so app-server doesn't outlive its parent as an orphan.

openjay · 1 month ago

Adding a longer-horizon data point from a different environment class: an always-on production build/CI server (M4-class Apple Silicon, 128 GB RAM, macOS 26.5.2) running containers and agent automation with a high process-spawn rate — no Codex Desktop involved. We hit the same daemon-side failure family repeatedly over Jul 16–22, which supports the view that high-spawn apps are amplifiers feeding an underlying macOS 26.x syspolicyd resource leak, rather than the leak being specific to any one app.

Sanitized measurements, in case they help triage:

  • RSS: healthy tens of MB → 6.4 GB in ~5 h (Jul 20); a successor instance that inherited an assessment-storm backlog reached 12.5 GB in 2 h 15 m (Jul 22).
  • EMFILE (error: 100024) storms: 40,151 log lines in 9 min; ~116,000 lines in 2.5 min during an app-update storm; 65,700 lines in a dying instance's final 10 minutes.
  • Disk churn: one .diag resource-exceedance report showed 34.36 GB written in 2 h, dominated by ExecPolicy SQLite WAL rewrites.
  • Trigger reduction helps but cannot cap it: cutting our process-spawn trigger sources by ~90% (≈3,000–3,400 fewer exec assessments/hour) extended the daemon's healthy lifespan from under a day to ~40–48 h — the leak still wins eventually, on a fairly regular rhythm.
  • Victim signature: Sparkle-style random-path updater helpers were policy-killed 2–3 ms after spawn — exit code 137, zero output, no .ips crash report — while their app bundles were verifiably intact (codesign --verify --strict passed).

Operational findings that may save others time:

  • Once the daemon is severely degraded, gktool scan itself fails (GKErrorDomain, exit 70), so a no-sudo recovery path does not exist — mild-episode advice involving gktool stops working exactly when you need it most.
  • launchctl kickstart -k system/com.apple.security.syspolicy is SIP-blocked (error 150), as already noted in this thread; sudo killall syspolicyd is the working restart — launchd respawns it within 1–2 s and already-running processes are unaffected.
  • The default launchctl limit maxfiles soft limit of 256 acts as an amplifier; raising it delays but does not prevent exhaustion — consistent with @nabong's follow-up above.

Since waiting for a human with sudo was not acceptable on an unattended server, we packaged our mitigation as a small MIT-licensed root LaunchDaemon watchdog: RSS/EMFILE thresholds, evidence capture (lsof fd total + top-10 fd targets) before restarting the daemon, a 30-minute cooldown to prevent kill loops, a 6-hour heartbeat, system-binaries-only execution for root-safety, and macOS's stock bash 3.2 compatibility:

https://github.com/openjay/syspolicyd-watchdog

(The watchdog repo previously linked in this thread appears to 404 now, so hopefully this fills the gap.) To be clear: it is a workaround for the OS-side leak, not a fix for the app-side spawn behavior discussed here — both still deserve fixes.

We have filed this data with Apple via Feedback Assistant, including the .diag reports and a sysdiagnose: FB23913699. Hoping the numbers help both the Codex team's app-side mitigations and Apple's triage.

openjay · 1 month ago

Follow-up to my earlier comment: the watchdog described there just captured its first two automated interventions — including per-fd attribution of what the leaked descriptors actually point at. Posting because automated fd-level capture data seems new to this thread.

Sanitized watchdog log excerpt (same macOS 26.5.2 production server as before; trigger thresholds: RSS > 500 MB or ≥5 EMFILE log lines per 5 min — errors_5m counts error: 100024 log lines in the trailing 5 minutes; 30-min cooldown between restarts; elisions marked […]):

2026-07-22T12:52:33+0800 HEARTBEAT status=running pid=29117 rss_kb=59696 etime=20:11
2026-07-22T12:57:39+0800 TRIGGER pid=29117 rss_kb=1035888 etime=25:13 errors_5m=103521 fds=2575 rss_max_kb=512000 err_max=5
2026-07-22T12:57:39+0800 FDTOP n=2536 target=/Applications/ChatGPT.app/Contents/MacOS/ChatGPT
2026-07-22T12:57:39+0800 FDTOP n=6 target=(ESTABLISHED)
2026-07-22T12:57:39+0800 FDTOP n=3 target=/dev/null
[… FDTOP remainder: SystemPolicyConfiguration {Tickets,KextPolicy,ExecPolicy}-shm ×2 each, /usr/share/icu/icudt78l.dat ×1, 3 single-fd lsof-parse artifact lines …]
2026-07-22T12:57:44+0800 KILLED old_pid=29117 kill_rc=0 new_pid=70077 new_rss_kb=374416
2026-07-22T13:02:47+0800 COOLDOWN over-threshold-but-in-cooldown last_kill_age_s=308 pid=70077 rss_kb=1060400 etime=05:05 errors_5m=54757
[… successor climbs 1.0 → 2.6 GB across the 30-min cooldown; errors_5m settles to 11–35 …]
2026-07-22T13:27:59+0800 TRIGGER pid=70077 rss_kb=3444736 etime=30:19 errors_5m=63 fds=2575 rss_max_kb=512000 err_max=5
2026-07-22T13:28:00+0800 FDTOP n=2537 target=/Applications/ChatGPT.app/Contents/MacOS/ChatGPT
[… identical FDTOP tail: 6 sockets, 3 /dev/null, -shm ×2 each, icudt78l.dat ×1 …]
2026-07-22T13:28:05+0800 KILLED old_pid=70077 kill_rc=0 new_pid=52479 new_rss_kb=372944
2026-07-22T13:33:07+0800 COOLDOWN over-threshold-but-in-cooldown last_kill_age_s=307 pid=52479 rss_kb=1052288 etime=05:05 errors_5m=141212
[… same pattern repeating: 1.0 → 2.9 GB by the 25-min mark; errors_5m settles to 5–20 …]

What it shows

  1. Per-fd attribution: at both triggers, 2,536 and 2,537 of 2,575 syspolicyd fds (~98.5%) pointed at a single target — /Applications/ChatGPT.app/Contents/MacOS/ChatGPT, the main executable of the ChatGPT desktop app. The remainder is the daemon's own working set (6 sockets, /dev/null, SystemPolicyConfiguration -shm files, ICU data). This is the same accumulation-on-the-assessed-executable pattern reported in #26117 / #26795, here reproduced independently (different app binary, no Codex CLI in the loop) and machine-timestamped. Notably, the plateau is near-identical to the live snapshots in #26117 (total_fd=2575–2576 with ~2,535 on the assessed binary), which looks like a hard internal ceiling rather than coincidence.
  2. Version correlation: ChatGPT desktop auto-updated to 26.715.71837 (build 5702) at ~12:54 local; the first trigger fired ~3 minutes later. The app itself runs normally the whole time — the damage is entirely on the daemon side.
  3. Leak rate under an active feeder: every freshly restarted syspolicyd re-crosses the 500 MB RSS threshold within ~5 minutes of birth and reaches 2.6–3.4 GB by the 25–30 minute mark, with EMFILE bursts (errors_5m = 103,521 / 54,757 / 141,212) clustered around each kill/respawn transition. For contrast: the previous daemon instance on this same machine — after we had cut ~90% of our own spawn-rate trigger sources — survived ~40 h. With this feeder active, it lasts minutes.

Practical note for anyone running the watchdog: with an active feeder the effective auto-restart cadence is ~30–35 min (30-min cooldown + 5-min poll grid). The machine stayed fully usable throughout — but to be clear, this is a treadmill, not a fix.

Full raw watchdog log available on request. We will also attach this capture to our existing Apple report FB23913699.

openjay · 1 month ago

Consolidated results to close out today's captures — continuing my initial data and the watchdog's first automated interventions.

The watchdog auto-restarted the leaking syspolicyd four times today (12:57 / 13:28 / 13:58 / 14:29 local; same macOS 26.5.2 production machine; ChatGPT desktop as the dominant feeder throughout). Across the successor instances we varied exactly one thing — whether/when gktool scan was run against the feeder app after the respawn (manually at first; v1.1 now automates it):

| Arm | Prewarm | Successor RSS trajectory | EMFILE (100024) |
|---|---|---|---|
| A (cycles 2–3) | none | ~375 MB at birth → 1.05 GB @ +5 min → 1.6–2.4 GB @ +15 min → 2.6–3.4 GB at kill (~30 min) | rebirth storms: 54k–141k log lines in first 5 min |
| B (cycle 4) | +90 s | 679 MB @ +5 min → 941 MB @ +15 min → plateau 991→998 MB @ +30 min | settled to 4–10 lines / 5 min |
| C (cycle 5) | +15 s | 58 MB at birth → 86 MB after 4.5 hours | zero |

Arm C is a flatline at healthy baseline: zero EMFILE lines and zero further watchdog triggers in 4.5 h and counting, under the same workload that had been forcing a kill every ~30 minutes. (Arm B's terminating kill was just our old 500 MB threshold firing on a healthy plateau, which is why v1.1 raised it. Timing note: a scan fired in the same second as the respawn reliably fails — GKErrorDomain, rc=70 — while +15 s succeeds.)

Key inference for triage: the fd/memory accumulation only accrues on the cache-miss assessment path. Once the feeder app's evaluation is warm in the fresh daemon's cache, the daemon holds baseline indefinitely under identical load — sustained assessment traffic per se is not what kills it; repeated cold evaluation is. Consistent with that, Arm B's trigger snapshot split its fds between the installed app's main executable (1,989) and a staged Sparkle update copy under the user's Caches directory (551) — a pending, not-yet-installed update (randomized path, so never cache-hittable) already feeding the accumulation, with the total still pinned at the ~2,574 fd ceiling noted earlier.

Watchdog v1.1 bakes both findings in: a post-kill prewarm hook (PREWARM_APPS list, ≥15 s delay, one retry) and the RSS threshold raised to 1.5 GB so the healthy post-prewarm plateau isn't misread as disease — https://github.com/openjay/syspolicyd-watchdog, commit 5a53cf9. Net effect on this machine: from a ~35-minute kill treadmill to zero interventions since.

This dataset (three arms + fd attribution) is also going to Apple on our existing report FB23913699 — hoping "leak accrues only on cache-miss assessments; warm cache = flat baseline" narrows the search space for both app-side mitigation and the OS fix.

themejunky · 1 month ago

Adding a current ChatGPT macOS data point that appears to match this issue exactly, with the runaway process narrowed to the bundled cua_node runtime.

Environment

  • ChatGPT macOS desktop app: 150.0.7871.124
  • Codex Framework: 150.0.7871.124
  • macOS: 26.5 (Darwin 25.5.0)
  • Apple Silicon

Observed behavior

The agent/computer-use helper:

/Applications/ChatGPT.app/Contents/Resources/cua_node/bin/node
  --experimental-vm-modules ...

became stuck at approximately 140% CPU for many hours, accumulating 16h51m of CPU time. It continuously spawned short-lived child processes, including:

  • node
  • node_repl
  • npx processes running from ~/.npm/_npx
  • codex app-server --listen stdio://

On macOS, each execution triggered a Gatekeeper/exec-policy assessment attributed to ChatGPT. The resulting churn exhausted syspolicyd’s file descriptors:

sudo lsof -p $(pgrep -x syspolicyd)

showed 2,540 of 2,574 descriptors open on:

/Applications/ChatGPT.app/Contents/MacOS/ChatGPT

Once exhausted, Gatekeeper failed system-wide:

spctl -a -t execute -v /bin/ls
/bin/ls: Too many open files

The unified log flooded with:

Failed to generate SecStaticCode ... error: 100024
UNIX error exception: 24

The downstream impact was severe and silent: LaunchServices and NSWorkspace.activateFileViewerSelecting opens of quarantined .dmg and .pkg files were dropped for every application. Even double-clicking a newly downloaded DMG no longer mounted it. CoreServicesUIAgent abandoned the open before launch without showing an error, so the visible symptom was simply that double-clicking downloads did nothing.

Restarting syspolicyd did not help while ChatGPT remained running; a fresh instance reached descriptor exhaustion again in under a minute. Force-killing the entire ChatGPT process tree drained the descriptors and restored Gatekeeper within seconds.

A normal Quit was also ineffective—AppleScript quit did nothing, and the process tree had to be terminated with SIGKILL.

Expected behavior

  • The bundled agent runtime must not enter an unbounded child-process spawn loop.
  • Retry/backoff and a watchdog should cap process churn.
  • Quitting ChatGPT must reliably terminate cua_node, app-server, Node REPL, and descendant processes.

Impact

This silently disables Gatekeeper-mediated opens for unrelated applications across the machine and is extremely difficult to attribute to ChatGPT.

I can provide additional sanitized process samples and unified logs if useful.

temujin-rambo · 1 month ago

Update: ChatGPT macOS 26.721.31836 / Framework 150.0.7871.128

A new data point from an Apple Silicon Mac Studio running macOS 26.5 (Darwin 25.5.0).

Environment

  • ChatGPT desktop: 26.721.31836 (build 5828)
  • Codex Framework: 150.0.7871.128
  • Bundled Codex: codex-cli 0.146.0-alpha.3.1

Observed behavior

Immediately after the app auto-updated and relaunched at 12:33 +05 on 2026-07-24:

  • 2,617 AppleSystemPolicy events in approximately 90 seconds
  • Target: /Applications/ChatGPT.app/Contents/Resources/codex
  • Typical message: ASP: Unable to apply provenance sandbox
  • The initial burst ended at 12:34:18; the app and full Codex stack remained running.

This is not strictly launch-only. After the app had been running for approximately 1h15m, additional bounded bursts were captured:

  • 446 matching events in a 5-minute window
  • a later 15-event burst at 13:48:27
  • 0 matching would not allow denials

At 13:59 +05, the final live sample showed:

  • 0 matching events in the previous 10 minutes
  • 0 denials
  • syspolicyd healthy at approximately 0% CPU / 48 MB RSS

So on .128 this appears to have changed from a continuous runaway storm into intermittent bounded bursts, but the problematic exec/assessment path is still active and can recur after launch.

Verified bundle delta from the official Sparkle artifacts (.124 → .128)

  • bundled Codex: 0.145.0-alpha.30 → 0.146.0-alpha.3.1
  • cua_node runtime: 0.0.4 → 0.0.5
  • node_repl: 20260713.2 → 20260716.1
  • Node remains 24.14.0
  • two duplicated Codex Computer Use.app copies were consolidated into one shared @oai/sky runtime

The shipped CODEX_SSH_SKIP_APP_SERVER_BOOT check is present in both .124 and .128 and appears unchanged. It only skips the remote nohup codex ... app-server --listen unix:// bootstrap; path/version probes and codex app-server proxy still execute.

Could the team confirm whether 150.0.7871.128 contains an intentional mitigation for this issue, and what AppleSystemPolicy event volume is expected during normal startup? At present, the evidence supports mitigated but not fixed.