app-server turn hangs indefinitely after a tool result — model stream stalls, no terminal turn event, thread unrecoverable (gpt-5.5 / xhigh)

Resolved 💬 2 comments Opened Jun 29, 2026 by amit777 Closed Jun 29, 2026

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-cli 0.142.3, run in codex app-server mode (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_command tools successfully.
  • Rollout JSONL's final record is a single reasoning item at 2026-06-29T04:12:44.978Z, immediately after a function_call_output; the file then stops being written.
  • ~443K input tokens on the stalling call.
  • ~12 min later, a turn/interrupt failed with thread 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 at 04:25:39Z, then total silence (tiny context).
  • ~2.5 min later, a turn/interrupt failed with thread 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-server that 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/failed before being reaped, so clients never perceive an infinite hang.
  • Investigate gpt-5.5 + xhigh reasoning 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).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗