Repository navigation
macOS Computer Use leaks SkyComputerUseClient turn-ended helpers #29157
Description
Codex Computer Use leaks SkyComputerUseClient turn-ended helper processes on macOS
Summary
Codex Desktop / Computer Use on macOS leaves SkyComputerUseClient helper processes running after turns complete. The leaked helpers include orphaned processes whose parent is PID 1 (launchd) and nested chains of:
SkyComputerUseClient turn-ended --previous-notify <json>
/bin/bash .../codex-notify.sh turn-ended -- SkyComputerUseClient turn-ended <json>
SkyComputerUseClient turn-ended <json>
This accumulates over time and survives normal Codex turns/sessions. The command payload contains turn metadata, so examples here are redacted.
Environment
- Host: macOS 27.0, build 26A5353q, arm64
- Codex.app currently installed: 26.616.32156, build 4157
- Originally observed version from the report: 26.608.12217
codexCLI:codex-cli 0.130.0- Computer Use bundle:
~/.codex/computer-use/Codex Computer Use.app - Computer Use bundle version:
CFBundleShortVersionString=1.0,CFBundleVersion=829 - Service executable:
.../Codex Computer Use.app/Contents/MacOS/SkyComputerUseService - Client executable:
.../SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient
Reproduction
- Enable/use Codex Desktop Computer Use or any Codex path that installs the
SkyComputerUseClient turn-endednotifier. - Run several Codex turns or Computer Use actions.
- Check helper counts and parentage:
ps -Ao ppid,comm | awk '/SkyComputerUseClient/{print $1}' | sort | uniq -c | sort -rn
ps -Ao comm | grep -c SkyComputerUseClient
ps -Ao etime,pid,ppid,comm | grep SkyComputerUseClient | sort -r | head
ps -Ao pid,ppid,etime,comm | grep -E 'SkyComputerUseService|MacOS/Codex$'Expected
After the relevant Codex turn/session ends, all per-turn SkyComputerUseClient helpers should exit. If the service exits, it should terminate and/or reap all children it spawned. A broken --previous-notify command should not leave the client process alive indefinitely.
Actual
Helpers remain alive for hours/days. On this machine, a previous run observed 1,422 simultaneous SkyComputerUseClient processes. In the current reproduction before cleanup:
ps -Ao comm | grep -c SkyComputerUseClientreturned22.ps -Ao ppid,comm | awk '/SkyComputerUseClient/{print $1}' ...showed7clients parented by PID1.- The oldest current helpers were over
02:13:00old. - The service process was alive as a child of Codex:
/Applications/Codex.app/Contents/MacOS/Codex
~/.codex/computer-use/Codex Computer Use.app/Contents/MacOS/SkyComputerUseService
Unified logs showed turn-end events with no active lock-screen threads while helper processes remained:
SkyComputerUseService: Received lock-screen turn end ... activeThreadCount=0 autoUnlockedThreadCount=0
Evidence
Info.plistidentifies the service ascom.openai.sky.CUAServiceand the nested client ascom.openai.sky.CUAService.cli.- Entitlements show both service and client share the
2DC432GLL2.com.openai.sky.CUAServiceapp group. - The bundled Computer Use plugin launches the MCP server via:
{
"command": "./Codex Computer Use.app/Contents/SharedSupport/SkyComputerUseClient.app/Contents/MacOS/SkyComputerUseClient",
"args": ["mcp"]
}- The leaked process command lines were
turn-endednotifier invocations, not active UI interaction commands. - The local
~/.codex/config.tomlhad been rewritten to:
notify = [ "SkyComputerUseClient", "turn-ended", "--previous-notify", "[...codex-notify.sh..., ...SkyComputerUseClient..., turn-ended]" ]
This creates a self-wrapped notifier chain when an existing wrapper already preserves the original SkyComputerUseClient turn-ended notifier.
Probable root cause
There are two lifecycle gaps:
SkyComputerUseClient turn-endedcan block indefinitely after spawning/invoking the previous notifier chain. Its parent exits or detaches, leaving the helper reparented tolaunchd.- The Computer Use service / installer wraps the existing Codex notify command without detecting that the previous notifier chain already includes
SkyComputerUseClient turn-ended, creating a nested self-wrapper. The service also does not reap staleturn-endedhelpers after turn completion.
Local mitigation installed
I installed a local, age-filtered mitigation:
- Reset
~/.codex/config.tomlto call the local notify wrapper first, then the originalSkyComputerUseClient turn-ended. - Hardened
~/.config/dev-knowledge/hooks/codex-notify.sh:- strips recursive
SkyComputerUseClient --previous-notifychains, - runs the original notifier with a bounded timeout (
DK_CODEX_NOTIFY_ORIGINAL_TIMEOUT_SECONDS, default20), - logs timeout/recursion warnings explicitly.
- strips recursive
- Added
/Users/jeremy/.local/bin/codex-computer-use-reaper.- Default threshold:
3600seconds. - Matches only the exact
SkyComputerUseClientexecutable path. - Redacts turn JSON in logs.
- Default threshold:
- Added and loaded LaunchAgent:
/Users/jeremy/Library/LaunchAgents/com.jeremy.codex-computer-use-reaper.plist- Runs at load and every 300 seconds.
Verification after mitigation:
- Dry-run found
16helpers,14older than 3600 seconds,2skipped as fresh. - Real run reaped
14stale helpers and left the2fresh helpers untouched. launchctl print gui/501/com.jeremy.codex-computer-use-reapersucceeds and reports interval300seconds.- Wrapper timeout test exits
124when a notifier exceeds the configured timeout; pass-through notifier test exits0.
Requested upstream fix
- Make
SkyComputerUseClient turn-endedalways exit after notifying the service and/or invoking--previous-notify, with a bounded timeout for the previous notifier. - Detect and reject recursive
--previous-notifychains that already includeSkyComputerUseClient turn-ended. - Ensure
SkyComputerUseServicetracks all spawned helper PIDs and tears them down on turn end/service exit. - Add a stale-helper guard in the service: cap concurrent helpers and terminate old
turn-endedhelpers safely.
Activity
github-actions commentedon Jun 20, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
PeterShanxin commentedon Aug 15, 2026
Same self-nesting notify chain reproduces on Windows (ARM64), not just macOS - with the Windows Computer Use helper
codex-computer-use-arm64.exe. Adding the platform data point plus a measured growth rate and a workaround that stops it.Environment
OpenAI.Codex_26.810.6296.0_arm64__2p2nqsd0c76g0Codex 151.0.7922.137...\AppData\Local\OpenAI\Codex\runtimes\cua_node\<hash>\bin\node_modules\@oai\sky\bin\windows\codex-computer-use-arm64.exeWhat
~/.codex/config.tomllooked likeLine 11 was a single
notifyentry wrapped inside itself 4 times, each level re-escaping the previous one as--previous-notify:--previous-notifylevelsStructure (elided):
Note the two levels reference different runtime hashes (
45b665c9b82ad082at the outer levels,be1d88aa93cd4c41at the innermost), so the chain has survived at least one runtime upgrade - the wrapper keeps pointing at helper binaries from older runtime directories.It grows on app start, and that is measurable
config.tomlmtime tracked the app launch exactly. Timeline from one session:09:08:50- app relaunched ->notifygained another nesting levelWorkaround that actually stops the re-injection
Deleting the
notifyline alone is not enough - it comes back on the next launch. What stopped it was disabling the feature as well:After that change, the app rewrote
config.tomltwice more (mtimes09:54:06and10:00:28, confirming it does rewrite the file at startup) andnotifywas not re-injected either time. Thecomputer_use = falseline was preserved across both rewrites.Related config left behind by Computer Use on Windows, for reference:
Suggested fixes
turn-endednotifier, detect that the currentnotifyvalue already points atcodex-computer-use*and replace it rather than wrapping it. The existing wrapper already preserves the original command, so re-wrapping is always redundant.notifyvalue beyond a sane length.Note
I found this while investigating an unrelated (and much larger) performance problem on the same machine - sustained ~1 GB/s of logical file reads from the Electron main process. I want to be explicit that I have not established any causal link between the notify nesting and that read storm; at 1,966 characters this line is far too small to account for it. Reporting the nesting purely as its own bug.
waml commentedon Aug 15, 2026
this is slowing down my mac to a crawl impossible to use desktop please reset tibo as compensation lmao