Hook-injected <hook_prompt> messages cause infinite loop, consuming billions of tokens with zero useful output
What version of Codex CLI is running?
codex-cli 0.144.5
What subscription do you have?
Pro
Which model were you using?
gpt-5.5
What platform is your computer?
Darwin 25.5.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
iTerm2 3.6.11
Codex doctor report
What issue are you seeing?
What issue are you seeing?
An external hook (registered in ~/.codex/hooks.json) that returns a <hook_prompt> message can cause an infinite loop where Codex keeps sending requests to the model with zero useful output, consuming billions of tokens.
In my case, a third-party "OMX" stop hook was registered. When the model finished a turn, the stop hook fired and injected a <hook_prompt> message into the conversation: "OMX cannot authorize Stop for unmatched session id ...". Codex treated
this hook output as a new user message and sent it back to the model. The model responded with a short acknowledgment. That response triggered the stop hook again, which injected another identical <hook_prompt> message — creating an infinite
loop.
Key metrics from the affected session (thread 019f7d3e-4dd2-77f0-b96d-83ad5778370e):
- Total tokens consumed: 343,651,633 (~3.44 billion)
- Duration: ~9 hours (02:38 UTC to 10:52 UTC, 2026-07-20)
- Total model requests: 1,843 — of which 1,789 (99.2%) were hook-injected messages, only 14 were real user messages
- 97% of requests produced output < 100 tokens — the model just repeated the same acknowledgment each time
- Each request grew the context window by ~8,000 input tokens as the conversation history kept expanding
- Context compaction occurred 6 times but did not break the loop
- The loop continued for ~9 hours until the weekly token quota was exhausted
What steps can reproduce the bug?
- Register an external hook in ~/.codex/hooks.json that fires on stop events and returns a <hook_prompt> message (e.g., a hook that cannot match the current session and returns an error message)
- Start a Codex session with any prompt
- After the model responds, the stop hook fires and injects its message
- Codex treats the hook output as a new user input → model responds → stop hook fires again → infinite loop
Thread ID: 019f7d3e-4dd2-77f0-b96d-83ad5778370e
What is the expected behavior?
Hook-injected messages should not automatically trigger new model requests in a loop. At minimum:
- Hook output should not be treated as new user input — messages from hooks should be informational only and not cause a new model turn
- Add a maximum auto-turn limit — if N consecutive turns have no real user input, the session should pause or stop
- Add debouncing/rate-limiting — identical hook messages within a short window should be suppressed
Without any of these safeguards, a misconfigured or incompatible hook can silently drain an entire weekly token quota with zero useful output.
Additional information
The same pattern also affected a second session (thread 019f5ecb-8ea4-73c0-a225-9ead151f6a78, 3.14 billion tokens) that was created on 2026-07-14 and continued running on 2026-07-20. The combined token waste from just these two sessions exceeded
6.5 billion tokens.
Workaround: Removing the offending hook from ~/.codex/hooks.json and the related entries from ~/.codex/config.toml stops the issue from recurring.
4 Comments
I can corroborate a closely matching failure mode on Codex Desktop for Windows.
Environment:
Observed on 2026-08-01 through 2026-08-02:
This symptom strongly matches the hook-triggered auto-turn loop described here, especially because Stop/compact hooks were active. I have not yet proved that the same hook message was the sole causal trigger on this Windows installation, so I am adding this as corroborating evidence rather than claiming an identical root cause.
The workspace also had a large instruction/skill stack. That may have amplified per-turn context cost, but it should not permit an unbounded sequence of model turns without new human input.
Safeguards that would have prevented the incident:
I am not attaching session transcripts because they contain private project material. I can provide redacted event counts or specific log fields if maintainers identify what would be most useful.
Incident impact addendum (Windows reproduction)
The original corroborating comment omitted the most important severity data. User-observed impact on 2026-08-01 was:
These figures are user-visible quota and outcome records, not inferred cost projections. Raw transcripts are not attached because they contain private project material.
Exact rollout reconstruction (replaces prior >500M estimate)
I reconstructed the affected local rollout families using each file's final
payload.info.total_token_usage.total_tokensand the childparent_thread_idgraph:019fbc65-...: 11 sessions, 420,775,426 tokens019fbd87-...: 5 sessions, 61,684,846 tokensThe original incident corresponds to the user-observed loss of approximately 80% of the weekly allowance (about 60% in the first run and another 20% after reopening). The previous ">500M" statement can now be treated as confirmed and refined to the exact local rollout total above.
Arithmetic correction
The exact reconstruction comment above contains one subtotal typo: recovery/harness task families total 76,001,530 tokens, not 76,001,247. The already reported original incident total (558,461,802) and cumulative total including the later failed reattempt (584,006,336) are unchanged.