app-server turn hangs indefinitely after a tool result — model stream stalls, no terminal turn event, thread unrecoverable (gpt-5.5 / xhigh)
Summary
A turn run through codex app-server intermittently hangs forever right after a tool/function-call result is returned to the model. The model response stream produces nothing further — no tokens, no response.completed, no error — no turn/completed or turn/failed is ever emitted, and the thread later reports thread not found when interrupted. Because there is no stream-idle / turn watchdog, the client (here, the app-server broker) reports running indefinitely.
Environment
codex-cli0.142.3, run incodex app-servermode (driven via an app-server broker over a unix socket)- Model
gpt-5.5,model_reasoning_effort = "xhigh" - macOS (arm64), Node v24, sandboxed
exec_command - A couple of stdio MCP servers were attached
Reproductions (2 in one session, same signature)
Repro 1 — thread 019f1192-99f2-77a1-b8ea-dd0b5a2d8ec1
- Ran several
exec_commandtools successfully. - Rollout JSONL's final record is a single
reasoningitem at2026-06-29T04:12:44.978Z, immediately after afunction_call_output; the file then stops being written. - ~443K input tokens on the stalling call.
- ~12 min later, a
turn/interruptfailed withthread not found.
Repro 2 — thread 019f119f-f8ed-7dd3-af83-182a45ffc98c
- Hung on the model's first turn: an MCP tool call (an MCP server's
initial_instructions) returned at04:25:39Z, then total silence (tiny context). - ~2.5 min later, a
turn/interruptfailed withthread not found.
Across both: the regular token_count heartbeat events that fired every prior tool round go silent at the stall instant, and the codex session rollout (~/.codex/sessions/YYYY/MM/DD/rollout-*-<threadId>.jsonl) simply stops appending.
Key observation
Context size is not the trigger — repro 2 hung on the first turn with a near-empty context. The common factors are: gpt-5.5 + xhigh reasoning, a tool-result round-trip, and the absence of any stream-idle/turn timeout that could surface a terminal event or retry.
Expected
A stalled model response stream should time out, emit a terminal turn/failed, and/or auto-retry — never hang silently and leave the thread unrecoverable (thread not found on interrupt).
Suggested fixes
- Add a stream-idle / turn-level watchdog in
app-serverthat fails the turn (with a terminal event) when no stream activity occurs for N seconds. - Guarantee that a thread which dies/errors server-side always emits
turn/failedbefore being reaped, so clients never perceive an infinite hang. - Investigate
gpt-5.5+xhighreasoning streams specifically on the tool-result round-trip.
Aggravating, separate
Under the sandbox, each exec_command runs via /bin/zsh -c, which fires the user's interactive zsh startup (rc) hooks; some of those hooks fail with operation not permitted and pollute every tool's output (and forced a Git retry). Consider running sandboxed exec with a no-rc shell (zsh -f / --no-rcs / bash --norc --noprofile).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗