Halfway through a long answer, the CLI stops writing and returns:
API Error: Stream idle timeout - partial response received
The session stays open and the history is not lost, but the turn ended there. The error starts inside the CLI, not in your account: a stream watchdog gave up on the response because bytes stopped arriving for too long. It shows up in different situations, with different fixes, and this guide separates each one.
What does "Stream idle timeout - partial response received" mean?
It means the response started and was cut in the middle. The first bytes arrived, the stream opened, and at some point between one chunk and the next the connection went silent until the watchdog fired and aborted the turn.
This is different from No response from API, which is the wait before the first byte. Here the answer was already flowing. What you lose is the part being generated, not the conversation: your message, the files read and the tools already executed stay in the session.

Why does the response get cut mid-stream?
Three causes cover almost every report, and each one needs a different fix. Identify yours before touching any config.
| Cause | How you spot it | What fixes it |
|---|---|---|
| Silence from the provider or the path to it | cuts on long turns, sometimes on all of them | raise the watchdog threshold |
| Proxy or gateway buffering the response | always cuts behind a VPN, gateway or ANTHROPIC_BASE_URL | test without the proxy and tune the retry window |
| The CLI's own keep-alive latch | the session degrades over time and a restart fixes it | restart the session or roll back the version |
I raised API_TIMEOUT_MS and nothing changed. Why?
Because API_TIMEOUT_MS is not the ceiling for a streaming response. The changelog spells out the behaviour: when the API sends no headers, the retry now waits up to API_TIMEOUT_MS, which defaults to 10 minutes. That is a deadline for getting an answer, not a clock measuring the silence between one chunk and the next.
Anyone who sees the idle timeout message and raises that number keeps hitting the same watchdog, because a different clock is the one that fired.
Which variable controls the stream watchdog?
It is CLAUDE_STREAM_IDLE_TIMEOUT_MS, which sets the streaming idle watchdog threshold and ships at 90 seconds by default. When no byte arrives inside that window, the turn is aborted and you see the partial response message.
| Variable | What it controls | Default |
|---|---|---|
CLAUDE_STREAM_IDLE_TIMEOUT_MS | streaming idle watchdog threshold | 90 seconds |
API_TIMEOUT_MS | how long the retry waits for a response with no headers | 10 minutes |
API_FORCE_IDLE_TIMEOUT | 5-minute idle timeout restored by default on Vertex and Foundry | active on those providers; 0 opts out |
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK | disables the non-streaming fallback when streaming fails | off |
Mind the scope of each one: CLAUDE_STREAM_IDLE_TIMEOUT_MS is the general stream silence watchdog, while API_FORCE_IDLE_TIMEOUT touches a timeout specific to Vertex and Foundry. If you are not on those two providers, that second variable is not your lever.
For a single session, export before opening the CLI. The value is in milliseconds, so 180000 is three minutes:
export CLAUDE_STREAM_IDLE_TIMEOUT_MS=180000
claude
To make it apply to every session, use the env block in ~/.claude/settings.json:
{
"env": {
"CLAUDE_STREAM_IDLE_TIMEOUT_MS": "180000"
}
}
In PowerShell the syntax is $env:CLAUDE_STREAM_IDLE_TIMEOUT_MS = "180000". After saving the file, run /status and check the Setting sources line to confirm the CLI loaded it.
Careful: raising the threshold prevents a premature abort, it does not repair a connection that dropped. If the cut always lands at the same point, with the clock near a round number, the problem is on the network path, not in the deadline.
Why does a long session get worse over time?
There is an aggravating factor in the connection pool. The changelog records the change: keep-alive is disabled after a stale connection so the retry opens a fresh socket. According to issue #100353, the code flips that switch and nothing turns it back on: the process starts opening a new connection for every request until it is restarted.
The author measured the effect in an orchestrator session with many subagents, on Linux, with the watchdog at 60 seconds:
| Scenario | Requests | Watchdog aborts | Gaps of 40 seconds or more | 400 continuation errors |
|---|---|---|---|---|
| With the latch active | ~1,725 | 131 (7.6%) | 66 | 101 |
| With the latch disabled in the binary | ~2,190 | 0 | 0 | 2 |
Those numbers come from that report, not from a measurement of ours, and the issue is still open. The signal is in the log: run with --debug-file and look for the line that starts with Stale connection and ends with disabling keep-alive for retry. After it, the session tends to degrade until you restart.
How do you fix it when a restart alone works?
If the log shows the latch, there are three ways out, ordered by cost:
- Restart the long session after the first warning. That is what the issue author does, and it drops the stall rate to zero.
- Run a CLI version from before the keep-alive change described in the issue, where the trigger was not active yet.
- If you must stay on the current version, turn off the non-streaming fallback, which is what turns a stall into a resend of the whole conversation:
export CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1
Item 3 does not fix the latch. It avoids the expensive effect, which is resending 0.35 to 1.1 MB of conversation on every stall, according to the same report.
Does the error appear on requests longer than 5 minutes?
Then the limit is a different animal. A report opened on 2026-11-04 with CLI 2.1.317, updated on 2026-11-07, describes a large local model served through ANTHROPIC_BASE_URL: any request that goes past 5 minutes is aborted, with a run of Request timed out. Retrying until the attempt limit.
In that scenario the stream watchdog is not the only piece involved, and the author points to a possible idle timeout in the runtime's HTTP layer. For a local model that takes more than 5 minutes per answer, the practical move is to split the task into smaller pieces or wait for the fix, not to raise a watchdog variable.
How do you make it less likely to happen again?
- Break long turns apart. Asking for a huge plan in a single turn is one of the scenarios that shows up in the reports.
- Run
/compactbefore long tasks, so the next turn has less context to sustain. - Test without a VPN, proxy or gateway when the error is constant, and compare against the direct API.
- In automation, prefer short headless sessions and restart between batches.
- Open long sessions with
--debug-file, so you see the latch before you lose the afternoon.
Verboo Code is the second route for when the first one freezes mid-turn: it runs in the same terminal flow and delivers unlimited tokens, so a long turn does not hit a quota while you investigate the stream. Keeping two paths configured keeps a single provider from stopping your day.



