[macOS] ChatGPT 26.810.52044 respawns SkyComputerUseService and crashes despite Computer Use disabled
Summary
The ChatGPT macOS desktop app repeatedly respawns SkyComputerUseService and then crashes, even when Computer Use and Remote Connections are disabled in the user configuration.
This is a new reproduction on ChatGPT desktop 26.810.52044 (build 6662) and appears related to the existing Computer Use / Node-V8 crash and helper-process reports.
Environment
- ChatGPT desktop:
26.810.52044(build6662) - macOS:
26.5.2 - Bundle ID:
com.openai.codex - Computer Use runtime:
26.812.1000717 - Apple Silicon Mac
Reproduction
- Fully quit ChatGPT and Computer Use helper processes.
- Set the effective app-server configuration to:
computer_use = falseremote_connections = false- no Computer Use
notifyhook
- Disable persisted remote-control state (
remoteControl/disablereturnedstatus=disabled) and clear the selected remote host / auto-connect map. - Launch ChatGPT desktop without invoking Computer Use.
- Observe the process tree.
Observed on a clean launch:
- ~8 seconds: 10
SkyComputerUseServiceprocesses - ~23 seconds: 149
SkyComputerUseServiceprocesses - ChatGPT then becomes unstable and crashes.
On launch, the desktop frontend also rewrites the Computer Use notify hook and re-selects a persisted remote-control:env_* host, despite the disabled effective app-server state.
Crash evidence
The latest ChatGPT crash report has:
EXC_CRASHSIGABRT/ Abort trap 6V8Workercomputer-usenode::OOMErrorHandler
The crash report was generated by ChatGPT desktop 26.810.52044 (build 6662). Full .ips data is available privately if needed; it is not attached here because it contains local paths and identifiers.
Expected behavior
When Computer Use and Remote Connections are disabled, ChatGPT should not launch or respawn SkyComputerUseService, and the desktop app should remain usable.
Actual behavior
The frontend calls the remote-control enable path and respawns many native Computer Use helper processes. Disabling the visible configuration, calling the app-server disable method, clearing persisted remote-host selection, and killing the helpers do not prevent the next launch from recreating them.
Impact
The desktop UI becomes unusable, helper processes consume substantial memory and process slots, and the main ChatGPT process exits. The current safe workaround is to keep the desktop app closed and use the web client.
Related reports
- #26079 - repeated Node/V8 OOM crashes in the desktop app
- #26458 - repeated Computer Use crashes and
node::OOMErrorHandler - #28244 - macOS helper/zombie process explosion at startup
- #25269 - multiple
SkyComputerUseServiceinstances respawn after being killed
Please route this to the ChatGPT desktop / Computer Use / remote-control owners. The key regression is that the frontend appears to re-enable and respawn Computer Use despite the disabled effective configuration.
7 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I independently reproduced what appears to be the same Computer Use spawn storm on macOS 26.6.1. I added a detailed A/B isolation test and process dump in #38771; blocking ~/.codex/computer-use stopped SkyComputerUseService spawning, and restoring it immediately reproduced hundreds of helpers, 300%+ mds_stores CPU, lag, and a Codex crash.
I hit this exact failure on the same build and think I have the root cause, plus a workaround that keeps Computer Use fully enabled.
Trigger: the Codex home / service path is spelled through a symlink.
In my setup the real Codex home lives on a separate APFS volume and
~/.codexis a symlink to it. That symlink spelling is what ends up inSKY_CUA_SERVICE_PATH, and it is what drives the storm. Canonicalizing every runtime path makes the storm disappear completely — same app, same version, same volume, Computer Use on.Why disabling Computer Use in config doesn't help
It doesn't, and I can confirm your finding.
[plugins."computer-use@openai-bundled"] enabled = falseand[mcp_servers.computer-use] enabled = falsedo not stop the managed service, and the app rewrites thenotifyhook back intoconfig.tomlon every launch. A launch with a completely emptyCODEX_HOME(noconfig.tomlat all) still produced 220 services in 65 s — so the spawn is not config-driven.Where the comparison goes wrong
From
app.asar: whenSKY_CUA_SERVICE_PATHis set it is returned verbatim, un-normalized, and then used asexpectedExecutablePathinwhich the CUA manager uses as
isExpectedServiceProcess. The expected path is built asserviceAppPath/Contents/MacOS/SkyComputerUseService.The AppleEvent is sent from
Contents/Resources/native/sky.node:sky.nodeimports bothposix_spawnandproc_pidpath, which is consistent with "spawn, read the PID's executable path, compare it to the expected path".proc_pidpathreturns the resolved path (/Volumes/...) whileexpectedExecutablePathkeeps the symlink spelling (/Users/<user>/.codex/...), so the two strings can never be equal. The identity/readiness check therefore fails every time, the PID is discarded, and a new service is spawned — with no readiness wait, no backoff, no single-flight, and no cap.So in this reproduction the
-600and thestdio_connection_closedEOF are downstream of the identity mismatch, not the initial cause.This is not TCC or LaunchServices: the AppleEvent targets a PID directly rather than resolving a bundle URL,
tccdlogged zero denials forcom.openai.sky.CUAServiceacross 20 minutes of storming, andsky.nodedoes not importSecCode*,realpath, orreadlink.There is a second un-normalized use as well: the "canonical refresh" step
dittos the source service into${CODEX_HOME}/computer-use/Codex Computer Use.appwithout canonicalizing first.Controls
Six configurations, each monitored 6 minutes (liveness,
ps -Mthread count,pgrep SkyComputerUseServicecount, and whether the main thread is still innextEventMatchingMask):| App location |
CODEX_HOME| Service path | Result ||---|---|---|---|
| External vol | symlink | via symlink | crash 158 s, 434 services |
| Internal disk | symlink | via symlink | crash 126 s, 385 |
| External vol | symlink | symlink → internal | crash 158 s, 417 |
| Internal disk | symlink | real | no crash, but 61 services leaked at startup, then flat |
| Internal disk | real | real | 1 service, stable |
| External vol | real | real | 1 service, stable |
What the matrix shows:
Also matching your report: 183 of 314 threads named
computer-use, all blocked inAESendMessage;Dispatch Thread Soft Limit Reached: 64; faulting thread a V8Worker innode::OOMErrorHandler;Abort trap: 6. Separately, the main/UI thread blocks innode::SyncProcessRunner::Spawn(child_process.spawnSync), which is why the window freezes before the crash.One secondary effect worth noting: TRACE logging into
logs_2.sqlitereached 2.47 GB / 81.4 M rows during the storms, after whichsqlx::pool::acquirestarted warningtime to acquire exceeded slow threshold acquired_after_secs=2.34. That amplifies the failure but is not the cause.Workaround (Computer Use stays fully enabled)
CODEX_HOMEat the real path, and make it visible to GUI launches:``
`launchctl setenv CODEX_HOME /real/path/to/codex-home
RunAtLoad` LaunchAgent — a plain shell export is not enough, because double-click launches only inherit the variable this way.Persist it with a
config.tomlto its real path (SKY_CUA_SERVICE_PATH,CODEX_HOME,CODEX_CLI_PATH,NODE_REPL_*trusted paths).Both steps are needed; doing only one leaves the 61-service startup leak from the matrix above. After this the app preserves the real paths when it rewrites
config.tomlitself. Result here: 1 service, no crash, 27 h continuous uptime with Computer Use enabled.Suggested fix
Environment: ChatGPT macOS 26.810.52044 (build 6662), Computer Use runtime 26.812.1000717, macOS 26.5.2 (25F84), Mac mini M4, Codex home on an external APFS volume reached via a symlink at
~/.codex.Possibly the same underlying cause as #38697.
Thanks @PMWang — this is very useful. I’m one of the users who reproduced the SkyComputerUseService spawn storm above.
One additional A/B result since my earlier comment: I rolled the ChatGPT/Codex app itself back from 26.810.52044 / build 6662 to 26.803.61601 / build 6396 using an Aug. 7 Time Machine copy, while keeping macOS 26.6.1, my existing Codex data/environment, and Computer Use enabled.
So far, build 6396 is stable and the SkyComputerUseService spawn storm has not reproduced. Restoring/running build 6662 had reproduced the storm immediately.
I have not intentionally configured ~/.codex as a symlink or moved CODEX_HOME to another volume, so I’ll check whether any relevant paths in my environment resolve through symlinks. If none do, my case may indicate there is another path-normalization/identity mismatch that can trigger the same underlying spawn loop.
I’ll report back once I verify the paths.
Independent reproduction on the same desktop and Computer Use builds.
Environment:
Observed:
node::OOMErrorHandleron a V8WorkerSkyComputerUseServicechildren under one ChatGPT process~/.codex/computer-use/Codex Computer Use.appaside stopped further growth; no later ChatGPT crash report appeared__assert_rtn/ IOSurface initializationThis matches the path-identity/restart-loop diagnosis above and reproduces on macOS 26.4.1 as well. The one-for-one replacement strongly suggests the running desktop process retains one restart controller per failed helper, so killing child processes cannot recover it; the app must be restarted after blocking the bundle.
I can provide the raw
.ipsreports privately after redaction if useful.Independent confirmation of the symlink/path-identity workaround described above.
In an affected setup,
~/.codexresolved through a symlink. The helper's expected path retained the symlink spelling while macOS reported the running executable using its canonical path. Making all related paths use one canonical spelling stopped theSkyComputerUseServicerespawn loop while keeping Computer Use enabled.The working sequence was:
realpath ~/.codex.CODEX_HOMEto that real path for GUI launches:``
sh
``launchctl setenv CODEX_HOME /real/path/to/codex-home
config.tomlto the same real path, including relevantNODE_REPL_*trusted paths/services.Setting only the environment variable was not sufficient while active config paths still used the symlink spelling.
After canonicalizing both the GUI environment and config, the app held exactly one Computer Use helper and remained stable through real read-only Computer Use calls. This is a useful workaround for the symlink-triggered case, not a complete product fix. The spawn path still needs canonical path comparison plus a single-flight guard, bounded backoff/process cap, helper cleanup, and a circuit breaker so any identity/handshake failure cannot create an unbounded process storm.
Thanks @iuxxoo for the independent confirmation — in particular for reproducing that setting only the environment variable is not enough while the active
config.tomlstill carries the symlink spelling. That matches the fourth row of my matrix (service path canonical,CODEX_HOMEstill symlinked → no crash, but a finite startup leak).@FourCLabs — a symlink here does not have to be intentional, so it is worth checking mechanically rather than from memory. macOS ships several by default (
/tmp,/var,/etc→/private/*), and a relocated or migrated home directory, a home on a second volume, or launching the app from~/Applicationsinstead of/Applicationscan all introduce one without anybody configuring it.This read-only check prints any path that resolves to something other than itself:
Reading the output: any
MISMATCHline for a path the app uses at runtime is a candidate trigger. One exception — after applying the workaround,~/.codexitself will still report a mismatch, and that is fine, becauseCODEX_HOMEand the config paths are the canonical ones and~/.codexis then only a human-facing entry point. That is exactly the state on my machine right now, stable.If your check comes back with no runtime mismatch, that is a useful result rather than a contradiction, and I would rather have that on the record than have my symlink case treated as the whole story. @brian-wijaya's report already points the same way:
SIGABRTin__assert_rtn/ IOSurface initialization. A helper that dies during startup for a reason entirely unrelated to paths will fail the same readiness/identity check, and therefore fall into the same retry loop. That is a second, symlink-independent entry point into the same defect.So I would summarise the current state of the thread as: the unbounded, uncapped, un-backed-off restart path is the product defect, and a path-identity mismatch is one reliable way to trigger it — reliable enough to be a clean repro, but not the only way in. The canonicalization workaround helps the symlink-triggered subset (mine, @iuxxoo's) and will not help someone whose helper is crashing on IOSurface.
@FourCLabs's rollback result is consistent with that framing too: 26.803.61601 (6396) stable, 26.810.52044 (6662) storming on the same machine, same data, Computer Use enabled — which would point at a change in the spawn/restart path in 6662 rather than at anyone's local setup.
For whoever picks this up: the identity comparison and the retry policy are separable fixes, and the retry policy is the one that bounds the blast radius no matter which trigger fires. Even with the path comparison left exactly as it is, a single in-flight spawn plus a readiness wait, bounded backoff, process cap and circuit breaker would turn every one of these reports from "app dies in 90–158 s and takes the machine's memory with it" into a logged, recoverable handshake failure.