[Windows][CLI 0.144.3] Codex silently exits while waiting on a tool after successful auto-compaction / PostToolUse activity
What version of Codex CLI is running?
codex-cli 0.144.3, installed globally with npm.
Note: 0.144.4 was installed after these incidents. Its release notes say there are no user-facing changes, and I have not repeated the destructive workload on 0.144.4 yet.
What subscription do you have?
Pro
Which model were you using?
gpt-5.6-sol with xhigh reasoning.
What platform is your computer?
Windows 11 Pro x64, build 26100.7171
PowerShell 5.1.26100.7019
Node.js v24.11.1
What terminal emulator and version are you using?
Windows console host / Windows PowerShell 5.1, interactive Codex TUI started from a dedicated visible PowerShell window with --no-alt-screen.
Codex doctor report
Not available. codex doctor --json did not produce a JSON report in the installed CLI.
What issue are you seeing?
During long-running autonomous CLI Goals, codex.exe terminates without a final message or diagnostic record.
The parent PowerShell remains open, but both the native Codex process and npm Node wrapper disappear. The rollout ends in the middle of a tool wait. There is no panic, fatal, turn_aborted, Goal completion event, or matching Windows Error Reporting/Application Error event for Codex, Node, or PowerShell.
This happened on multiple recovery attempts:
- A resumed, high-context session ended while polling a running shell tool.
- A fresh session with a reduced MCP/app surface and an early auto-compaction threshold also ended while waiting on a shell tool.
The fresh run is the important case because auto-compaction completed successfully first. The active context dropped to about 19k tokens and was only 26,889 tokens immediately before termination. One focused test completed successfully (5 passed in 0.24s). A second shell test started, emitted 15 passing dots, and the final visible TUI status became:
Running 5 PostToolUse hooks
The process then disappeared and the console returned directly to the PowerShell prompt. The launcher's post-exit diagnostic statements did not run.
A user-level command hook was enabled for PostToolUse. Only one PostToolUse command definition exists; "5 hooks" therefore appears to be concurrent/pending hook activity, not five separate configurations. The hook is correlated with the failure but is not proven to be the root cause.
What steps can reproduce the bug?
The workload is not yet a minimal deterministic reproducer, but the controlled recovery scenario was:
- On Windows, enable command hooks for lifecycle events including
PreToolUseandPostToolUse. - Launch an interactive CLI Goal from PowerShell with a reduced configuration:
codex -C <workspace> --no-alt-screen --disable apps `
-c model_auto_compact_token_limit=160000 `
-c model_auto_compact_token_limit_scope=total `
-c mcp_servers.<unrelated-server>.enabled=false `
"<long autonomous task>"
- Let the Goal use three subagents and overlapping shell-tool calls.
- On the root agent, run a test/tool command that exceeds the initial tool yield and launches ordinary PowerShell subprocesses.
- Let Codex poll/wait for the running tool while subagent tool calls complete.
- Observe the TUI reach
Running 5 PostToolUse hooks, then return directly to PowerShell with no final rollout event.
Sanitized hook configuration:
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "<node> <third-party-hook.js>",
"timeout": 30
}
]
}
]
}
}
The active unit tests that could invoke WMI/detached-process behavior were explicitly skipped. The executed code used ordinary PowerShell subprocesses.
What is the expected behavior?
Codex should remain alive until the tool and hooks finish.
If a tool, hook, subprocess, compaction step, or process-group operation fails, Codex should:
- record the failing component, exit code, timeout, stderr, and termination reason;
- isolate hook cancellation/failure from the parent CLI process;
- preserve the tool as a recoverable pending/unknown state;
- emit a terminal failure/aborted event instead of silently ending;
- allow an active Goal to reattach without leaving ambiguous partial state.
Additional information
Confirmed:
- Early auto-compaction worked in the fresh session.
- Context exhaustion cannot explain the fresh post-compaction termination by itself.
- The rollout ended during the long tool wait without a matching result.
codex.exeand the Node wrapper disappeared while the launcher PowerShell remained.- No matching WER/Application Error, Resource Exhaustion event, panic, or fatal log exists.
- No pytest/build process remained afterward.
- Disabling hooks for a single invocation is accepted and leaves Goals, MCP, and multi-agent features available.
Hypotheses, not confirmed root causes:
- A Windows race/unhandled exit path involving hook fan-out, long-running tool polling, and child process/job/console-control handling.
- The console behavior is compatible with a control-event interruption, but no exit code or dump was produced, so
STATUS_CONTROL_C_EXITis not claimed as confirmed.
Impact:
This repeatedly interrupts multi-hour autonomous tasks, leaves a dirty working tree and durable Goal ledger partially advanced, and requires manual fencing/reconciliation before safe continuation.
Related but not duplicate:
- #18067: large hook payloads fail silently on Linux/Windows.
- #21753: hook parity tracker notes incomplete PostToolUse, subagent, compaction, and cross-surface behavior.
I can provide sanitized rollout excerpts, exact timestamps, process-tree snapshots, Windows event exports, and session IDs privately to OpenAI maintainers. The complete rollout is not attached publicly because it contains proprietary repository paths, prompts, and source context.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Sanitized diagnostic evidence (2026-07-14)
This comment adds the smallest useful evidence set without publishing private workspace paths, source text, prompts, account data, or full session identifiers.
Observed timeline (local time, UTC+08:00)
Running 5 PostToolUse hooks.Negative / exclusion evidence
turn_completed,turn_aborted, panic, fatal error, or Goal terminal event was written.Hook configuration relevant to this run
PostToolUsecommand was configured (PowerShell -> a local Node hook), with a 30-second timeout.SessionStartandStophooks were also configured.Current mitigation / comparison run
I upgraded the CLI to 0.144.4 and started a fresh recovery session with per-process flags:
hooks=falsegoals=truemulti_agent=trueThat comparison session successfully created a new rollout and an active Goal. I will update this issue if it exits in the same way.
Root-cause confidence
The evidence is compatible with a Windows process/control-event or hook/tool-wait lifecycle race, but it is not sufficient to claim an exact exception code or a single hook implementation as the cause.
The raw rollout and local logs contain private project paths, source fragments, and prompts, so I am not attaching them publicly. I can provide a further-sanitized excerpt or original files through a maintainer-provided private channel.
Follow-up: reproduced on 0.144.4 with Hooks disabled; Goal continuation survived (2026-07-14)
A second sanitized observation materially narrows the earlier hypothesis.
Isolation configuration
The recovery run used Codex CLI 0.144.4 with per-process configuration:
Result
Important continuation behavior
The same Goal did not stop. Codex App's app-server subsequently continued the same rollout and protected project ledger:
active;This is useful positive evidence for Goal durability, but it also means the CLI exit is not explained solely by the previously configured third-party PostToolUse hook, because Hooks were disabled for this process. It also reproduced with only one MCP server.
The remaining evidence is more consistent with a broader Windows CLI/PTY/process-lifecycle failure than with context exhaustion or a specific hook implementation. I am retaining the local sentinel receipt and can provide it through a private maintainer channel.
The fresh-run evidence here is especially useful: auto-compaction completed, context was low, then Codex disappeared while waiting on a shell tool and the rollout ended with no result or terminal event.
That is a strong unfinished-tool-call recovery test. Codex Rescue is local-first and does not assume whether the test or PostToolUse hook finished. It keeps the original rollout untouched, does not replay the command, and preserves unknown side effects for manual review.
If you still have that rollout, could you run:
pipx install codex-rescue==0.1.0a3codex-rescue sessionscodex-rescue doctor --latestSanitized diagnostic output only is sufficient—please don’t publish the rollout, hook commands, repository data, prompts, paths, databases, or secrets.
https://github.com/shleder/codex-rescue
Status update + Codex Rescue results (2026-08-16)
Thanks — the rollout is preserved. I ran
codex-rescue 0.1.0a3against it, plus aregression sweep over every rollout I have since the incident. Sanitized output only.
1. Codex Rescue on the original incident rollout
Run read-only (
doctor, nosalvage) against the preserved 0.144.3 root rollout:This independently reproduces the report from the rollout alone: compaction
completed, 31 further operational events were written, and the session then ends
holding exactly one unfinished
waitcall — i.e. Codex died while polling arunning shell cell, not while starting or finishing one.
recoverable_prefix: true,and the tool left the original untouched, as documented.
Thread topology at death (from the rollouts, not from Rescue): the root TUI thread
and all three subagent threads terminated within the same ~20-second window, each
mid-tool-call. A simultaneous whole-process-tree death is more consistent with a
process/console-level event than with per-thread tool logic.
2. Two Codex Rescue issues worth fixing
Both are tool-side, not Codex-side:
UNKNOWN_OPERATIONAL_SCHEMAis a false positive here. The only flagged recordis a valid
event_msg/mcp_tool_call_endpayload, which the parser does notrecognize. It fires on healthy current-format sessions too (see below), so on
today's rollouts it masks the real status — the genuinely interesting finding
(
UNFINISHED_TOOL_CALL) gets outranked by a parser gap.REPO_STATE_DIVERGEDfires unconditionally on non-git workspaces. Theworkspace is SVN, so
gitstatefails withfatal: not a git repositoryand theresult is reported as divergence rather than "VCS not supported / unknown".
confidence: unknownis set correctly in the JSON, but the top-line finding doesnot reflect that.
3. Regression status: not reproduced since 0.145.x
Scanning every local rollout for the failure signature — session ends with an
unresolved tool call and/or no terminal event (
task_complete/turn_aborted):| Window | Versions | Rollouts | With compaction | Signature hits |
|---|---|---|---|---|
| Incident, 2026-07-14 | 0.144.3 | — | yes | 4 (root + 3 subagents) |
| 2026-07-14 → 07-16 | 0.144.4, 0.144.2 | — | yes | 2 |
| 2026-07-17 → 08-08 | 0.145.0 → 0.147.0-alpha | 208 | 169 (2,456 compaction events) | 0 |
In the clean window: 21 active days, 176 rollouts with subagent activity, and every
single rollout terminates with an explicit event (197
task_complete, 11turn_aborted) — no silent ends at all.Exposure was maintained, so this is not survivorship bias from a changed setup:
command hooks stayed enabled throughout (
features.hooks = true, withPostToolUseplusPreToolUse/SessionStart/UserPromptSubmit/Stop/PermissionRequestcontinuously configured across that period), long autonomousruns continued, and auto-compaction fired heavily.
Caveat on what this can and cannot prove. Rollout forensics cannot distinguish
"the CLI never exited" from "the CLI exited and the app-server resumed the same
rollout cleanly" — which is exactly what happened in my second (0.144.4) report,
where the rollout ended at a clean tool boundary. So I can state that the
unfinished-tool-call silent-exit signature has not recurred, and that no rollout
in the clean window ends without a terminal event; I cannot claim from this data
alone that no CLI process ever exited unexpectedly. I no longer run the external
process sentinel that caught the original exit, and I have not deliberately re-run
the original destructive workload as a targeted reproducer.
Given no recurrence across that window, I am fine with this being closed as stale
unless maintainers want it kept open pending a deterministic reproducer. If it
returns I will reopen with sentinel data.
Your interrupted
waitreproduction is preserved in the Rust adapter as boundedUNFINISHED_TOOL_CALLcorrelation; no tool call is replayed.Migration update: active Codex Rescue development has moved to Vetto: https://github.com/shleder/vetto. The standalone
shleder/codex-rescuerepository remains public as compatibility history. User installation is nownpm install --global @shleddy/vetto@next, with recovery undervetto rescue. The boundary remains read-only/copy-only and does not modify session JSONL or vendor SQLite. The newest diagnostic changes are merged into Vettomainand will be included in a later npm alpha; no source install is requested.