Codex Desktop crashes entire application due to missing tool call result
What version of the Codex App are you using (From “About Codex” dialog)?
26.707.6957.0
What subscription do you have?
pro 20x
What platform is your computer?
Windows 11 x64
What issue are you seeing?
After today's update, Codex now crashes with the following error which stops all threads, which is highly nonideal given the relatively non-severe nature of the error.
(code=3221225786, signal=null).
Most recent error: {"timestamp":"2026-07-12T22:28:09.945506Z","level":"ERROR","fields":{"message":"Custom tool call output is missing for call id: call_gU4LyYUSjHVTKriG83dAFWSY"},"target":"codex_core::util"}
The tool call that it was attempting to achieve was an exec tool call to run a local pytest [I had mistakenly believed it was from an ssh-mcp exec, but was wrong].
What steps can reproduce the bug?
Attempting to open a conversation that had a failed exec tool call.
What is the expected behavior?
A failed tool call should be treated as simply that and not _crash the entire application and all threads_.
Additional information
_No response_
12 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
When I had 5.6 Terra investigate this, it attempted to back-patch in a missing tool call so that it wouldn't fail, which instead led to the following issue occurring when I attempted to reopen the thread:
(code=3221225786, signal=null).
Most recent error: {"timestamp":"2026-07-12T22:44:11.844541Z","level":"WARN","fields":{"message":"ignored world-state patch without a full snapshot"},"target":"codex_core::session::rollout_reconstruction"}
Despite this being a "WARN" level it still _crashed the entire application_.
and this one too now. it's whackamole. these things are only happening after this recent update. I'm going to try to downgrade at this point.
(code=3221225786, signal=null).
Most recent error: {"timestamp":"2026-07-12T22:55:35.033836Z","level":"WARN","fields":{"message":"Model personality requested but model_messages is missing, falling back to base instructions.","model":"gpt-5.6-sol","personality":"friendly"},"target":"codex_protocol::openai_models"}
Independent Windows Desktop reproduction with a closely matching failure signature.
Environment
26.707.8168.0codex-cli 0.144.0-alpha.4gpt-5.6-solultranone(also tested with the personality feature disabled)Visible failure
The Desktop error screen reports:
The most recent visible log entry is:
However, the structured backend log shows a more specific boundary immediately before the worker disappears:
No completed custom-tool input or tool output follows. The native
codex.exeworker exits abruptly, while the Desktop process remains alive and starts a replacement worker. The existing task can continue after recovery/reload. I observed this pattern more than once.An isolated
gpt-5.5shell-tool smoke test succeeds on the same machine and authentication, which points away from the shell, permissions, or repository itself. The failure is specific to the GPT-5.6 customexectransition on this installation.This appears related to:
CustomToolCall(status=in_progress, input="")gpt-5.6-sol+ personality fallback + recoverable process-unavailable stateThe personality message may only be the last warning surfaced by the crash screen rather than the actual fatal condition. A guard that treats an incomplete custom-tool item as a recoverable stream error—and reconnects/retries instead of terminating the worker—would prevent the whole Desktop failure.
Local paths, task contents, and call IDs have been redacted.
Independent Windows Desktop reproduction with persisted-rollout evidence.
Environment
26.707.8479.00.144.20.144.1[features].unified_exec=falseFatal event
Focused reproduction
The persisted rollout contains an
execcustom-tool call recorded at2026-07-13T06:57:29Zwith no matching tool-call output. It was a harmless container-status query. Desktop resumed that task at2026-07-14T01:44:30Z, started a new turn at01:44:38Z, and app-server failed on the stale unpaired call at01:44:42Z. Desktop observed process exit at01:44:53Zand initialized a replacement app-server successfully at01:44:57Z.The affected rollout had 616 tool calls and 612 outputs; four calls were unpaired, including the fatal stale call and the new call interrupted by this crash. At least three concurrent task streams were active in the focused crash window, so termination of the shared app-server interrupted all of them.
The same Desktop build also logged another
Custom tool call output is missingfatal event at2026-07-13T11:21:46Zfor a different call ID. This is separate from a previously mitigated Windowsunified_exec/stale-process failure.This points to persisted incomplete tool-call history being replayed on task resume. A missing tool result should interrupt only the affected turn or be represented as a recoverable failed result; it should not terminate the shared app-server and every active task.
I did not modify or back-patch the rollout because the earlier report here notes that doing so can trigger another fatal rollout-reconstruction error. Local paths, task contents, commands beyond their harmless category, and credentials are omitted.
Additional Windows desktop evidence (no prompt, project, or session contents included):
Environment
0.144.0-alpha.4.config.tomlparses successfully (codex mcp listsucceeds), and Microsoft Store/winget reported no manual upgrade available before the in-place AppX update.Observed failure
code=3221225786, signal=nullat2026-07-13T19:14:41.978845Z.execcall,call_TxIyvHyslfmwG4sYFzfVM3bO, was recorded at2026-07-13T19:06:19Z, but there is no matchingcustom_tool_call_outputevent in the local transcript.execcalls have no matching output event (2.69%). At least the call above is confirmed to have culminated in the crash dialog; the remaining unmatched events are transcript anomalies and should not all be assumed to be crashes.Likely mechanism
The event order matches the persisted-rollout replay mechanism described in comment #4964649683: an incomplete custom-tool call remains in the rollout, and the shared app-server terminates when a later task/session resume tries to reconcile it. Locally, the unmatched call above was followed by a new task start about 7.98 minutes later, immediately before the fatal window.
Why long instructions appear to trigger it
The data does not show an input-size threshold. The unmatched calls occurred after instructions ranging from 28 to 4,111 characters, and their tool payloads were small (mostly 330–566 characters; one was 2,191). The stronger correlation is tool-heavy/long-lived work: more tool calls create more chances for the custom-tool result bookkeeping to lose an output event, which then persists into a later resume. This aligns with the long tool-heavy pattern reported in #14824.
Update-state observation
After the automatic AppX update, the persisted user config still contained app-generated references to the prior runtime binaries, which were no longer present. This may be secondary, but it indicates that an in-place desktop update can leave stale tool-runtime references while a session is active.
Expected behavior: a missing or failed tool result should be surfaced as a recoverable tool failure (or retried), not crash the entire desktop application or interrupt every active task.
I can provide sanitized event timestamps/call IDs if maintainers need them.
Independent reproduction on a newer Windows Desktop build, with one additional failure mode that may help narrow this down.
Environment
26.707.9981.0config.tomlparses successfully with PythontomllibReproduction 1: missing output after a trivial exec
This has occurred in multiple unrelated tasks. In one focused case, the custom tool call was only:
The call was persisted at
2026-07-14T07:56:24.504Z, but no matchingcustom_tool_call_outputwas stored before a new turn began at07:57:08.549Z. Reopening/resuming the affected task then produced:This shows the problem is not limited to long-running or high-output commands.
Reproduction 2: normal apply_patch rejection also crashed Desktop
At
2026-07-14T12:33:58.397Z, anapply_patchcall targeted lines that had already changed. At12:33:58.459Z, the rollout correctly stored a matchingcustom_tool_call_outputcontaining:That is a normal, recoverable patch-context mismatch. However, Desktop still showed the whole-app crash dialog with
code=3221225786, using that tool error as the most recent error.This may be a related error-propagation path rather than the exact missing-output path, but both turn ordinary tool failures into shared app-server termination.
Mitigations already tried
write_stdinand all control-character interrupts in subsequent reproductions.The issue still reproduced on short commands and on an expected
apply_patchverification failure.Impact
Several unrelated tasks became unsafe to reopen and had to be archived, while all active work was interrupted when the shared app-server exited. This is severely disruptive for normal coding work.
Expected behavior: persist an explicit aborted/error output atomically when a turn is superseded or a tool fails; if a historical call is unpaired, recover or quarantine only that turn/task. A normal tool failure or stale task record should never terminate the shared app-server.
Local paths, task contents, and call IDs are omitted. Sanitized event excerpts can be provided if needed.
Correction / withdrawal
I am withdrawing the conclusion in my previous comment that the nested approval boundary was the cause of my reproduction.
Follow-up investigation found a deterministic local trigger in the project under test: Python code called
os.kill(pid, 0)as a PID-liveness probe. That is a POSIX idiom but is unsafe on Windows. In CPython on Windows, signal value0collides withCTRL_C_EVENTand is routed throughGenerateConsoleCtrlEvent. When run inside Code Mode, the resulting console control event can interrupt the tool process and the App Server sharing that console/control domain, producing0xC000013A / STATUS_CONTROL_C_EXITand leaving an unmatched custom tool call.After replacing the Windows probe with
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION)plusGetExitCodeProcess, the complete test suite finished successfully (57 passed) without an App Server restart.Please disregard my earlier comment as evidence that approval escalation itself caused these exits. This correction applies to my reproduction only; it does not invalidate the issue author's report or the independent reproductions above.
Windows warning: do not use
os.kill(pid, 0)as a process-existence check. Use a Windows-specific non-signaling process query or an OS-backed lock instead.Current macOS evidence — Desktop 26.803.61601
A read-only aggregate of the current structured log found 181 messages matching the missing-tool-output error class between approximately 23:58 and 02:30 UTC during concurrent tool-heavy tasks.
Environment: macOS arm64, Codex Desktop
26.803.61601, bundled CLI0.147.0-alpha.6.5.No whole-app crash was observed during this audit, so this comment does not claim the same crash outcome as the original Windows report. It confirms that missing tool-call results still occur at high volume in a current desktop build and can affect many turns. Call IDs, task IDs, prompts, paths, account data, and raw logs are omitted.
I’m testing Codex Rescue
0.1.0a3against real broken-session cases, and the persisted missing-tool-output boundary here is a direct match for one of its diagnostics.Rescue can detect an unfinished/orphaned tool call from the rollout, preserve the original file unchanged, and create a bounded handoff. It does not back-patch or invent the missing tool result.
If you still have one affected rollout, would you be willing to try:
If it finds the affected session, sanitized
doctor/salvage --fork/verifyoutput would help validate this on a real Desktop crash case. Please don’t share the raw rollout, prompts, DBs, credentials, or private paths.https://github.com/shleder/codex-rescue
Deterministic Windows MRE: abrupt child termination crashes Codex Desktop and corrupts the task transcript
Environment
OpenAI.Codex_26.818.5229.0_x64__2p2nqsd0c76g00.149.0-alpha.4.1Minimal reproduction
Run this as a Codex Desktop
exectool call on Windows:os.kill(pid, 0)is a POSIX liveness-probe idiom. In this Windows Python environment it terminates the child process instead of providing that probe. The abrupt child termination is the intentional trigger.Expected
Codex Desktop remains open and records a terminal tool result (an ordinary failed/aborted
execresult is sufficient). The task remains resumable.Actual
Codex Desktop exits. The task JSONL contains a built-in
custom_tool_callnamedexecwithout a matchingcustom_tool_call_output. Reopening or continuing the task can then immediately fail with:Why this was found
My project used
os.kill(pid, 0)to check a QA lease-owner PID. That made apytestchild terminate and deterministically triggered the Desktop failure. I replaced the Windows implementation withOpenProcess(PROCESS_QUERY_LIMITED_INFORMATION)and preserved the POSIX implementation on non-Windows systems. A fresh separate Desktop task then completed:Result:
71 passed, 7 subtests passed; Desktop did not crash.This avoids the trigger in my project, but the standalone MRE above still shows that Desktop must tolerate abrupt child-process termination and must not persist an orphaned tool call.
Impact / requested fix
Root-causing this, repairing affected task history, and eliminating the project trigger consumed approximately 10% of the weekly usage allowance on a $100 plan.
Please make interrupted or abruptly terminated tool calls persist a terminal error/aborted output, and make transcript recovery tolerate unresolved historical calls instead of terminating the app-server.
Independent Windows Desktop reproduction on a newer Store build. Same fatal class as this issue: persisted unpaired
custom_tool_callbecomes a shared app-server abort on resume.Environment
OpenAI.Codex26.820.7780.0(config/runtime still referenced26.820.60940immediately before this incident)0.149.0-alpha.4at thread start[features] unified_exec = falseandshell_snapshot = falsewere already set[windows] sandbox = "elevated"kept (official Windows recommendation)The config pin did not stop PTY
tools.write_stdin(...)customexeccalls. Desktop still records those in rollouts.Two-stage failure (this is the part that looks like “it was fine for a week”)
A new local thread (started after quarantining older poisoned rollouts) ran normally for ~7 days and grew a large tool-heavy rollout (~2k
write_stdinexecs).Stage A — unpaired call is created (overnight, ~2026-08-27T04:55Z):
codex.exeexited3221225786(0xC000013A/STATUS_CONTROL_C_EXIT). Desktop log “most recent error” was an MCP shutdown warning (cloudflare-apiOAuth refresh missing an authorization-server issuer). The Electron UI stayed up. The rollout kept a customexec/write_stdincustom_tool_callwith no matchingcustom_tool_call_output.Stage B — resume makes it fatal (~2026-08-27T14:54–14:58Z):
On next use, Desktop auto-resumed that thread plus several other local threads (
thread/resume). After a few minutes of continued work, app-server fatal-exited:That killed the shared app-server, so every other open thread dropped too. No Application Error 1000 / Hang 1002, no Crashpad dump. Rollout scan: 5212 custom tool calls / 5210 outputs (2 unpaired). A second unrelated local thread from the previous day already had 2 unpaired calls and would have been the next landmine.
Did not back-patch the JSONL (that path caused another fatal in earlier comments here). Recovery was Fully Quit, move only the affected rollout files out of
sessions/, relaunch, continue in a new chat.What this adds
write_stdincan be poisoned by a later0xC000013Adeath.unified_exec = falseinconfig.tomlis not sufficient on current Desktop; the app still persistswrite_stdinexecs.No prompts, repo contents, local paths, or credentials included. Happy to provide sanitized timestamps if useful.
Related: #33136 (same exit code), #40231 (26.818+ Windows console-control regression still present on 26.820).