Codex Desktop activity can repeatedly crash macOS WindowServer in IOSurface/ScreenCapture path
What happened
While using Codex Desktop on macOS, WindowServer crashed repeatedly in the same day. The user saw three WindowServer incidents today; two crash reports were available and the latest report has consecutiveCrashCount: 3.
This appears related to Codex/Computer Use or browser automation interacting with macOS screen/window capture. The crash stack is in the macOS WindowServer/SkyLight/IOSurface/Metal capture path rather than in a normal app process.
What I expected
Codex Desktop should not leave macOS in a state where WindowServer repeatedly aborts. If Codex uses ScreenCaptureKit/window capture/Computer Use/browser screenshots, those capture streams should be scoped to the active session and should not destabilize WindowServer after or between tasks.
Steps to reproduce
The exact minimal repro is not isolated yet, but the observed scenario is:
- Run Codex Desktop on macOS with active Codex tasks that use the desktop app/browser/computer-use surfaces.
- Continue normal Codex work involving browser/app inspection and screenshot/capture-capable tooling.
- Observe
WindowServercrashes/restarts multiple times during the day. - Inspect
/Library/Logs/DiagnosticReports/WindowServer-*.ips.
Environment
- macOS 26.5.2 (25F84), arm64
- Hardware model: Mac17,9
- GPU: Apple M5 Pro, Metal 4
- Display at time of current inspection: built-in Liquid Retina XDR only, 3024 x 1964 Retina
- Codex Desktop app bundle:
com.openai.codex, version26.730.61639 - Related existing issue: #35659 reports Codex Computer Use leaving a ScreenCaptureKit stream running and causing high WindowServer GPU. This report may be the same class of bug but the symptom is more severe: WindowServer SIGABRT crashes.
Crash evidence
Two WindowServer crash reports from 2026-08-05 were inspected:
WindowServer-2026-08-05-152542.ips
macOS 26.5.2 (25F84), Mac17,9
consecutiveCrashCount: 2
exception: EXC_CRASH (SIGABRT)
termination: Abort trap: 6
fault frames:
__pthread_kill -> pthread_kill -> abort ->
CI::Context::AbortIfUnhandledError ->
-[CIContext _startTaskToRender:toDestination:forPrepareRender:forClear:error:] ->
-[CIContext render:toMTLTexture:commandBuffer:bounds:colorSpace:] ->
CA::OGL::MetalContext::render_ciimage ->
CA::OGL::emit_filter -> CA::OGL::FilterNode::apply
WindowServer-2026-08-05-164638.ips
macOS 26.5.2 (25F84), Mac17,9
consecutiveCrashCount: 3
exception: EXC_CRASH (SIGABRT)
termination: Abort trap: 6
kernel triage: VM - (arg = 0x1) vm_map_copyout_kernel_buffer failed
fault frames:
__pthread_kill -> pthread_kill -> abort ->
WSIOSurfaceDebugTallyAndAbort -> iosurface_create_common ->
WSIOSurfaceCreateTargetableWithFormatAndProtection ->
CaptureSurfaceMetal::CreateMetalBacking ->
CompositorMetal::CreateCaptureSurface ->
WS::Capture::create_iosurface_for_window_list ->
_CGXCaptureContentToIOSurfaces -> _XCaptureContentToIOSurfaces
Both reports also showed com.apple.VirtualDisplayListener plus multiple com.apple.coreanimation.*.external-* threads. That seems relevant because the active display inspection later reported only the built-in display.
A separate WindowServer_2026-08-05-093213_*.cpu_resource.diag also appeared earlier the same day. It attributed samples partly “On Behalf Of: Codex (Service)” and showed heavy WindowServer composition/rendering activity.
Additional context
- No full
.ipsfiles are pasted here to avoid leaking machine/user identifiers, but the stack snippets above are copied from the local crash reports. - I did not find a normal app crash for Codex at the same moment; the user-visible failure is macOS WindowServer crashing.
- There was no obvious
panic-fullreport corresponding to these WindowServer crashes, so this initially looks more like a capture/GPU/WindowServer interaction bug than a physical hardware failure. - A useful diagnostic path may be to check whether Codex/Computer Use/browser screenshot capture can leave ScreenCaptureKit, virtual display, or capture surfaces active across task boundaries, and whether capture teardown failures can trigger repeated IOSurface creation failures in WindowServer.
1 Comment
Update from August 6 — fresh crash on 26.6 + independent cua_node dyld loop
Updating this issue with a same-day reproduction on macOS 26.6 (25G72) and a second failure mode that may be related.
Hardware / Software snapshot (today)
12377.161.13~4com.openai.codex, version26.730.616390.146.0-alpha.9.2(matches the profile @galligan identified in #35659)Same path, third incident now on 26.6
WindowServer-2026-08-06-120805.ips— created 2026-08-06 12:08:05 CST, 50 minutes after a prior identical crash on the same install. Thread 0 is byte-identical to the 16:46 evidence already attached to this issue:Kernel, in the minutes before the abort (verbatim from
log show):Both 65024 messages are post-upgrade and pre-crash; same threshold the user saw on 26.5.2.
Live state right now (WindowServer up 3:35 min, currently overstressed)
WindowServerPID 34312, 10.8% CPU; at 12:10:45 the kernel reports:caught waking the CPU 45001 times over ~167 seconds, averaging 268 wakes / second and violating a limit of 45000 wakes over 300 seconds. It is back to running but taxed far above normal.codex35276 (3m old) +codex35460 (2m old — Codex restarted after the previous crash and immediately re-attached the same children)cua_node35319, 35342, 35520, 35536 — four Computer Use childrenreplayd34529duetexpertd34681 — repeatedly failingIOSurfaceSharedEventAddEventListeneron this installIndependent failure mode —
cua_nodedyld bootstrap crash loopTwenty-one
node-*.ipsfiles in~/Library/Logs/DiagnosticReports/from 11:05 to 12:09 CST. All coalesce to a single incident — sameslice_uuidacross every report:Stack on every report:
usedImagesresolve to/opt/homebrew/*/...for every image (node,libnode.147.dylib,libuv.1.0.0.dylib,libllhttp.9.4.3.dylib, etc.) even though the actual binary lives at/Applications/ChatGPT.app/Contents/Resources/cua_node/bin/node_repl. dyld emits a wildcard path when its cache pointer fails to bind@rpathto a real on-disk location, then rejects linkage atdyld4::prepare. Everycua_nodesurvives ~7.2 s and dies on SIGABRT.coalitionName: ai.lark-channel-bridge.bot.codex— confirming thesecua_nodes were spawned from a Codex session.I do not know whether Symptom B is caused by Symptom A or independent. Two plausible mechanisms:
cua_nodecannot establish a transient display attachment within dyld's prepare grace → dyld rejects and aborts.cua_nodeships anLC_LOAD_DYLIBthat points at a path that does not exist inside the bundle's rootless container.Both can be true simultaneously; distinguishing them needs controlled isolation I cannot run today.
Workaround that holds
Quitting Codex is not sufficient (matches the existing workaround in the OP). What does hold:
After that, WindowServer CPU drops, IOSurface count returns to baseline (verified via
sysctl kern.ipc.iog_global_state_countfamily / per-process footprint), and no further aborts.Frequency
Six confirmed
WindowServeraborts across 3 days on this machine, all on the sameWSCaptureCreateIOSurfaceMachPortForWindowListcall path. With Codex Computer Use enabled, this is now a less-than-2-hour reproducer on current shipping macOS — not a corner case.What would help, in priority order
SCStreamis torn down whenever no consumer is attached. @galligan's #35659 already names the path: the registered-thread set is never cleared on idle, so the supervisor keeps respawning per-thread clients even after the model turned off.event-stream mcpclient lifetime to a single turn, not to a registered thread that may never be deregistered.ChatGPT.app/Contents/Frameworks/libnode.*.dyliband haveLC_LOAD_DYLIBuse@executable_path/../Frameworks/libnode.*.dylib, not a Homebrew path that does not exist inside the bundle's rootless container.WindowServerCPU or liveSkyComputerUseClient event-stream mcpcount) and refuses to spawn a new Computer Use turn past a red line.Attachments available on request
WindowServer-2026-08-06-120805.ips(63,879 B) — captured at 12:08:05, Thread 0 above is verbatim from this file.node-2026-08-06-1*.ipsfrom 11:05 to 12:09 CST, all coalescing to one logical incident.sampleof WindowServer taken at 12:08:25 (post-restart, while overstressed).vmmapsummary across all fourcua_nodechildren at the same instant.The whole session stash lives at
~/Documents/diagnostics/windowserver-2026-08-06/. Happy to attach any subset. /cc @openai/codex maintainers — this is the same class as #35659 / #29157 / #26293 and is now reproducible within hours on shipping macOS.