codex - 💡(How to fix) Fix Codex Desktop can remain in Thinking after successful tool calls with no streamed follow-up or a hung /responses request

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Codex Desktop can remain in the UI Thinking state after tool calls have already completed successfully. After inspecting local session JSONL and core SQLite logs across several affected turns, the visible Thinking state appears to cover multiple distinct backend states:

  1. A stale turn state after a successful tool result, with no further session events emitted until the user interrupts.
  2. A follow-up /responses request that is started after successful tool results but then produces no streamed output for several minutes, until the user interrupts.
  3. Context compaction after tool output, which can look similar in the UI but does eventually resume.
  4. A long-running model request after tool output that eventually returns, also shown only as Thinking.

This makes it hard to tell whether the model is actually reasoning, the backend request is hung, compaction is running, or the turn runner is stale.

Error Message

  • If a follow-up /responses stream produces no events for a long time, Codex should emit a timeout, retry, or visible recoverable error.
  • If no model request is pending and no events are emitted after tool success, the turn should not remain open without task_complete, turn_aborted, or an error event.

Root Cause

From the user's perspective, all of these cases look like the same Thinking state after tools have already succeeded. The only practical workaround is to interrupt the turn and continue, but interruption can lose momentum and may leave turns in confusing states.

Agent-level instructions such as "after tool success, promptly respond" do not fix the hung cases because the model does not regain control while the follow-up request is pending or the runner is stale.

Fix Action

Fix / Workaround

In one affected turn, the last tool call was an apply_patch that completed successfully. After the tool result was written, there were no further session JSONL events until the user interrupted several minutes later.

T+0s     custom_tool_call_output: apply_patch success
T+0s     token_count
T+216s   user interrupt
T+216s   turn_aborted

From the user's perspective, all of these cases look like the same Thinking state after tools have already succeeded. The only practical workaround is to interrupt the turn and continue, but interruption can lose momentum and may leave turns in confusing states.

Code Example

T+0s     custom_tool_call_output: apply_patch success
T+0s     token_count
T+216s   user interrupt
T+216s   turn_aborted

---

reasoning
message
function_call
function_call_output
token_count
task_complete

---

T+0s       function_call_output: success
T+0s       function_call_output: success
T+0s       function_call_output: success
T+0s       token_count
T+492.7s   user interrupt
T+492.7s   turn_aborted

---

post sampling token usage
  total_usage_tokens=117208
  estimated_token_count=Some(96568)
  auto_compact_scope_limit=244800
  token_limit_reached=false
  model_needs_follow_up=true
  has_pending_input=false
  needs_follow_up=true

stream_request: POST /backend-api/codex/responses

---

T+0s    function_call_output: success
T+0s    token_count
T+~30s  context_compacted
T+~35s  reasoning resumes

---

POST /backend-api/codex/responses
Request completed: status=200, duration_ms=149510
reasoning emitted afterward
RAW_BUFFERClick to expand / collapse

Summary

Codex Desktop can remain in the UI Thinking state after tool calls have already completed successfully. After inspecting local session JSONL and core SQLite logs across several affected turns, the visible Thinking state appears to cover multiple distinct backend states:

  1. A stale turn state after a successful tool result, with no further session events emitted until the user interrupts.
  2. A follow-up /responses request that is started after successful tool results but then produces no streamed output for several minutes, until the user interrupts.
  3. Context compaction after tool output, which can look similar in the UI but does eventually resume.
  4. A long-running model request after tool output that eventually returns, also shown only as Thinking.

This makes it hard to tell whether the model is actually reasoning, the backend request is hung, compaction is running, or the turn runner is stale.

Environment

Sanitized environment from affected runs:

  • Product: Codex Desktop
  • Client version observed in logs: 26.519.81530
  • Core/app version observed in telemetry: 0.133.0
  • OS: macOS, arm64
  • Model: gpt-5.5
  • Reasoning effort: xhigh
  • Approval policy: never
  • Sandbox: full local access
  • Auth mode: ChatGPT

Account identifiers, email addresses, exact local paths, thread IDs, and prompt contents have been intentionally omitted.

Observed Patterns

Case A: tool success followed by no session activity until interrupt

In one affected turn, the last tool call was an apply_patch that completed successfully. After the tool result was written, there were no further session JSONL events until the user interrupted several minutes later.

Sanitized event sequence:

T+0s     custom_tool_call_output: apply_patch success
T+0s     token_count
T+216s   user interrupt
T+216s   turn_aborted

During that interval there were no new session entries of these types:

reasoning
message
function_call
function_call_output
token_count
task_complete

This suggests the UI was still showing Thinking, but there was no visible evidence that the model was actively reasoning or that any new tool work was pending.

Case B: tool success followed by a follow-up /responses request that hangs

In another affected turn, multiple shell tools completed successfully. The runner then decided a model follow-up was required and started a new /responses request. No streamed output was produced for over eight minutes, until the user interrupted.

Sanitized session sequence:

T+0s       function_call_output: success
T+0s       function_call_output: success
T+0s       function_call_output: success
T+0s       token_count
T+492.7s   user interrupt
T+492.7s   turn_aborted

Relevant sanitized core log signal:

post sampling token usage
  total_usage_tokens=117208
  estimated_token_count=Some(96568)
  auto_compact_scope_limit=244800
  token_limit_reached=false
  model_needs_follow_up=true
  has_pending_input=false
  needs_follow_up=true

stream_request: POST /backend-api/codex/responses

There was no Request completed log and no streamed reasoning, message, function_call, or token_count event before the interrupt.

This suggests this instance was not local tool execution and not visible local reasoning; it was a pending follow-up model request that did not produce output or a failure event for several minutes.

Case C: tool success followed by context compaction

A separate affected-looking interval was actually context compaction. In that case, tool output completed, then a context_compacted event appeared around 30 seconds later, and reasoning resumed shortly after.

Sanitized sequence:

T+0s    function_call_output: success
T+0s    token_count
T+~30s  context_compacted
T+~35s  reasoning resumes

This is less concerning functionally, but the UI still only showed Thinking, making it indistinguishable from the stuck cases above.

Case D: long follow-up request that eventually returns

Another case showed a post-tool follow-up /responses request taking around 149 seconds before returning. It eventually emitted reasoning, so it was not permanently stuck, but it looked identical to the hung case in the UI while waiting.

Sanitized signal:

POST /backend-api/codex/responses
Request completed: status=200, duration_ms=149510
reasoning emitted afterward

Expected Behavior

After tool calls complete successfully, Codex Desktop should avoid silently staying in Thinking indefinitely.

Ideally:

  • If a follow-up model request is pending, the UI should distinguish "waiting for model response" from "reasoning".
  • If a follow-up /responses stream produces no events for a long time, Codex should emit a timeout, retry, or visible recoverable error.
  • If the runner has needs_follow_up=true but no progress occurs, there should be watchdog logging and a task-level failure or recovery path.
  • If context compaction is running, the UI should identify that state separately.
  • If no model request is pending and no events are emitted after tool success, the turn should not remain open without task_complete, turn_aborted, or an error event.

Why this matters

From the user's perspective, all of these cases look like the same Thinking state after tools have already succeeded. The only practical workaround is to interrupt the turn and continue, but interruption can lose momentum and may leave turns in confusing states.

Agent-level instructions such as "after tool success, promptly respond" do not fix the hung cases because the model does not regain control while the follow-up request is pending or the runner is stale.

Potentially Related Issues

This may overlap with or provide more granular diagnostics for:

  • #24336
  • #21360
  • #24571
  • #24618

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING