[BUG] "Waiting for API response · check your network" during thinking is a 60 s stall in the thinking-summary step (showThinkingSummaries: true), no network problem

Status Open
Reported on v2.1.287
Maintainer reply None cached
Activity 2 comments · opened Oct 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

With "showThinkingSummaries": true the request carries thinking.display: "summarized", and the API then streams a summary of the thinking, chunk by chunk (about 400 thinking tokens per chunk, one call to a second model each, delivered in order while the model keeps thinking). Normally the first summary text lands about 3 s after the block opens and a short think costs about 2 s extra. Sometimes one of those summary calls is very slow: the stream goes silent (only a keep-alive ping at 30 s) until it answers, 20 to 60 s later, and then continues normally with the late summary. 60 s is the cap: calls that reach it come back cut or empty. The summary that follows is usually fine to read; measured over 42 stalled blocks in my transcripts it is about half as long per thinking token as a normal one (median 0.65 vs 1.45 chars per token for 301 to 1,000 token blocks), and 7 of the 42 came back empty or under 12 characters. Nothing fails, nothing is retried, the reply arrives complete. Claude Code shows Waiting for API response · will retry in … · check your network after 20 s of that silence, so the user is told to check their network for a wait that happens on the server, inside the summary step.

Side by side test, same login, same prompt (a short counting puzzle, ~140 thinking tokens), pairs started in the same second, the only difference the thinking display mode (2026-10-05 21:07 to 21:13 UTC):

| Model | display | Runs | Thinking block p50 | p90 | Max | Blocks of 20 s or more |
|---|---|---|---|---|---|---|
| Opus 5.5 | omitted | 348 | 1.1 s | 1.4 s | 2.6 s | 0 |
| Opus 5.5 | summarized | 348 | 3.0 s | 4.5 s | 61.9 s | 6 |
| Fable 5.1 | omitted | 60 | 1.1 s | 1.2 s | 1.3 s | 0 |
| Fable 5.1 | summarized | 60 | 3.2 s | 4.3 s | 61.1 s | 2 |

7 of the 8 long blocks took 61.1 to 61.9 s for ~140 thinking tokens: a 60 s deadline plus the normal second or two. In those runs the stream shows the thinking block start, a ping at 30.0 s, then the block closing near 61 s with 1 to 13 summary deltas instead of the usual 20 to 27.

In real interactive sessions (transcript thinkingDurationMs against thinking_tokens), 2026-10-05 17:00 to 20:42 UTC, one Mac, one account: sessions with summaries on had 36 stalls in 291 thinking replies (12.4%, 29 stalls per thinking hour, 29.7 min lost); headless runs without summaries at the same time had 13 in 1,943 (0.67%). The rate per thinking hour is flat across thinking block sizes, so each summary call is an independent draw and long thinking turns are hit most (30.6% of replies with 1,001 to 3,000 thinking tokens). It comes in stretches: Oct 1 0 of 197, Oct 3 4 of 1,546, Oct 4 1 of 1,663, Oct 5 39 of 1,083, nearly all after 17:00 UTC. The status page listed no incident. The target model matters a lot: stalls per thinking hour in terminal sessions with summaries on, Oct 1 to 6: Opus 5.5 15.9, Fable 5.1 4.1, Fable 5 0.4, Sonnet 5.5 0.0.

Two client-side problems make this hard for users to see or report:

  1. The banner says check your network and shows a retry countdown, but there is no network problem and no retry: the stream is open and the API pings it at 30 s. The banner clears on the ping, then returns from second 50 to 60. A healthy thinking block never shows it: with summaries off the stream carries an estimated_tokens delta every 1 to 2 s, with summaries on the summary paragraphs arrive every few seconds, so bytes keep flowing. The banner appears only when the summary step is stuck, and it blames the user's network for it. Note this never errors and never aborts: the reply always arrives complete. #98887 (banner only, 2.1.287) looks like the same thing. #76555 and #88061 mix it with real failures (Response stalled mid-stream, API ERROR, turns that had to be continued), which hit the 180 s idle abort and are a different problem.
  2. The spinner's ↓ N tokens counter does not move during thinking, even though with display: "omitted" every thinking_delta carries estimated_tokens about every 1.2 s. StreamingPreviewController.recordApiMetricsEvent already adds that estimate to _responseLength, but only addResponseLength (text and tool input deltas) mirrors _responseLength to the UI, so the counter sits still until the first text delta. I patched my own build to call the throttled mirror after recordApiMetricsEvent grows the length (one line) and the counter now climbs at ~120 tokens/s while Opus 5.5 thinks, so a stalled stream shows as a number that stops. Subagents already get this upstream: the subagent progress path adds thinking_progress deltas into its own token counter, so a subagent's line climbs while it thinks. Only the main spinner was left out.

What Should Happen?

  • A slow summarizer call should not hold the stream. If a summary call runs long, the API should fall back to omitted or updates display for that chunk, or at least keep streaming estimated_tokens deltas so the client sees progress.
  • The client should not say check your network while the stream is receiving pings; a wait inside an open thinking block is a server wait.
  • The ↓ N tokens counter should follow thinking progress (the stream already carries it) so progress is visible during a think and a stall shows as a number that stops, well before the 20 s banner.

Error Messages/Logs

Waiting for API response · will retry in 2m 40s · check your network

Steps to Reproduce

  1. In a busy stretch (for me 17:00 to 23:00 UTC these days), run the same prompt headless in both display modes, several pairs at once, stamping every stream event on arrival:
P="How many integers from 1 to 10000 are divisible by none of 6, 10 and 15? Work it out, then reply with just the number."
for i in 1 2 3 4 5; do for d in summarized omitted; do
  claude -p --safe-mode --tools '' --model claude-opus-5-5 --effort high --thinking-display $d \
    --output-format stream-json --verbose --include-partial-messages <<<"$P" \
  | python3 -c 'import sys,time;t0=time.monotonic();last=t0
for l in sys.stdin:
  now=time.monotonic();g=now-last;last=now
  if g>20: print("'$d'", "silence %.1f s" % g, l[:80])' &
done; done; wait
  1. Repeat a few hundred pairs. Only the summarized arm shows silences, and they cluster at 61 s. With omitted the longest thinking block in 408 runs was 2.6 s.
  2. Interactive: set "showThinkingSummaries": true, start a session, ask anything that thinks. In a bad stretch the Waiting for API response · check your network banner appears on 5 to 30% of replies with no network issue; with the setting false it does not.

Claude Model

Opus 5.5, Fable 5.1, Fable 5

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.290 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Terminal: Ghostty. macOS 27.2. Max 20x subscription. Headless claude -p does not read showThinkingSummaries, so headless tests look clean unless --thinking-display summarized is passed, which is why this stayed hidden behind "something in your network" for a week here.

View original on GitHub ↗

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