Back to guides
Coding agents·September 21, 2026·Updated October 1, 2026·8 min read

ZeroClaw stream interrupted: recovery and retry boundaries

The documented boundary is whether you had already seen output. Run on v0.8.5, the terminal client drew a different one: no retry at all with one candidate, a re-send to the second model with two.

Last reviewed on .

ZeroClaw never resumes a broken stream. Whether it sends the turn again depends on how many candidates your profile has, and on the only current release it is not quite what the documentation promises. ZeroClaw's documentation for v0.8.5 (published September 5, 2026) says a stream that fails before any output is retried without streaming, and one that fails after output is never replayed. Run on October 1, 2026 against an endpoint that cut the stream mid-reply, v0.8.5's terminal client did something simpler: with one candidate it sent no retry at all, before or after text had appeared; with a second candidate it re-sent the turn, without streaming, to that second model — even after part of the answer was already on screen. Guided recovery after partial output is an open feature request that has not reached design sign-off. So the useful question is not how to make ZeroClaw retry. It is whether your turn is safe for you to re-send, and what the dead attempt already cost.

Two scope notes before any of this is actionable. What was run is narrow: the v0.8.5 release binary in its interactive terminal mode, one OpenAI-compatible endpoint, and a local test server that closed the stream on purpose — the results are below. Channels, the gateway WebSocket, RPC, ACP, the Anthropic slot and real provider outages were not run. Every other claim is read from the repository at release tag v0.8.5, from the version-pinned documentation at docs.zeroclaw.com/v0.8.5/, or from dated upstream issue reports, all on September 21, 2026. And pin that URL yourself: the README sends readers to the /master/ path, whose HEAD is sixteen days ahead of the release and which contradicts it on exactly this subject, while /latest/ returns 404. ZeroClaw here means the zeroclaw-labs/zeroclaw runtime; if you are not certain that is what you are running, ZeroClaw vs OpenClaw separates it from the projects and forks that share the name.

Four markers at v0.8.5, and only one of them is the network

Before deciding anything, read which marker you actually got. ZeroClaw's English locale file at v0.8.5 defines these as distinct Fluent keys under a header comment saying they are appended to, or persisted as, assistant output when a turn is cut short, and shown to end users across every transport — channels, WS, RPC, ACP and CLI.

MarkerFluent keyWhat it tells you
[stream interrupted]turn-stream-interruptedThe transport stream died mid-turn. Nobody pressed stop.
[interrupted by user]turn-interrupted-by-userA human interrupt.
[turn cancelled via client]turn-cancelled-client-rpcThe channel, not the actor. Its own code comment says human interrupts and programmatic client cancels both arrive on this path, so the wording names the channel.
[interrupted by user before this tool produced a result]turn-tool-interrupted-before-resultA tool was cut off before returning.

A fifth key, turn-failed = [turn failed], exists in the same file on master but is not in v0.8.5's locale file, so a released build does not emit it. One behavior worth knowing because it changes what you can read afterwards: the turn engine persists the partial text with the marker appended only when that partial text is non-empty. A turn that produced reasoning or provider-side pre-executed tool events but no visible text persists nothing at all — the code comment frames persistence as committing what the consumer already saw. Other locales carry the same keys with translated values, so the literal English bracket string is not what a non-English install shows.

Where the retry boundary actually sits

The whole decision reduces to one question: had anything reached an immutable event sink yet?

What happenedDocumented behavior at v0.8.5Caveat
Stream fails before any visible outputThe runtime retries the whole call through the non-streaming path, re-entering the full reliability walkDocumented, but not what a single-candidate setup observed on the released build — see below
Stream completes with no final text and no tool callsA semantic-empty response, not an answer. When the result is marked replay-safe and provider_retries is nonzero, one non-streaming recovery call to the exact same provider and model, consumed onceShipped in v0.8.5 via pull request #10602, merged September 4, 2026. Applies to empty streams, not to streams that broke mid-output
Text, reasoning or pre-executed tool events already reached an immutable event sinkStreamInterruptedAfterOutput. The runtime does not replay the request, and text already forwarded to the consumer is all that becomes persisted partial assistant textDeliberate and identical on master. Locked by a regression test asserting a stream error after visible output must fail the turn with no fallback retry
Any of the aboveThe stream is opened once and entries are not switched after it has startedRecovery is always a new request. No provider family, including the custom slot, gets a resume path

The knobs that do exist are global, not per endpoint. [reliability] carries provider_retries, documented default 2, and provider_backoff_ms, default 500, and the lifecycle doc states each materialized entry is attempted up to provider_retries + 1 times. The v0.8.5 config reference documents no per-provider or per-alias retry override alongside them. Do not count on the key pool either: v0.8.5's documentation says reliability.api_keys is not a working failover today, because the wrapper selects and logs an alternate key after a retryable rate limit but cannot apply it to the constructed provider, so the retry still uses the original credential. A second key you added expecting a rescue does not provide one.

Pointing at one endpoint is the configuration that gets hurt

This is the sharpest boundary for anyone running ZeroClaw against a single gateway or a single vendor endpoint, because one endpoint is by definition a single-candidate reliability configuration. Issue #10736 reports that on the released build a pre-output stream failure in that shape logs a fallback to non-streaming chat and then never sends it, killing the turn with All model providers/models failed after 0 failure event(s). It closed September 18, 2026 — after v0.8.5 was published — so the fix is on master only. Run on October 1, 2026, the released v0.8.5 behaved exactly as the issue describes: one request, then that error, whether the stream broke before or after text appeared.

Two official positions disagree here and both are worth carrying. The v0.8.5 architecture doc promises the non-streaming retry; the issue demonstrates the released build not performing it, and its expected-behavior section asks that the log only claim a fallback when one will actually be attempted. Master then adds a single-candidate recovery allowance the release does not have — and issue #10787 said that allowance was granted with RetryDecision::Admit(0) regardless of provider_retries and with no backoff, so an overloaded upstream was re-sent immediately into the same shed window. That issue was closed as completed on September 26, 2026 — on master, after v0.8.5, so in no release either. Master's behavior is still moving; do not plan against it.

The documented shape of a mitigation is configuration rather than a setting: give the profile a second candidate so the reliability walk has somewhere to go. On October 1, 2026 that worked on v0.8.5 in the terminal — with one caveat worth knowing before you rely on it: the recovery request went to the second model, not the first, so the answer you get after a break comes from your fallback. The ZeroClaw API cost and setup guide covers the config shape those entries go in.

What v0.8.5 did when the stream was cut

On October 1, 2026 the v0.8.5 release binary, checksum-verified against the release's SHA256SUMS, ran in a throwaway container in interactive terminal mode — the mode that streams; single-message -m mode sends one non-streaming request and never reaches this path. One OpenAI-compatible custom-slot profile, provider_retries = 2, pointed at a local test server that answered with a normal stream and then closed the connection without [DONE], either before the first event or after one chunk of text.

ProfileWhere the stream brokeRequests sentWhat the terminal showed
One candidateBefore any textOne streaming request, no retryError: The selected model provider failed. Review provider configuration or choose another provider. The log: All model providers/models failed after 0 failure event(s)
One candidateAfter text was printedOne streaming request, no retryThe partial text, then the same error. No [stream interrupted] marker was printed
Plus fallback_models with a second modelBefore any textThe streaming request, then one non-streaming request to the second modelThe second model's reply
Plus fallback_models with a second modelAfter text was printedThe same two requestsThe partial text, then the second model's whole reply — so the answer appears twice

Three things follow for anyone running ZeroClaw from a terminal on v0.8.5. The one-candidate failure is #10736, reproduced; provider_retries did not change it. The documented "no replay after visible output" boundary did not apply here: text already printed in the terminal did not stop a re-send, so a turn you watched half-arrive can still be sent again, to a different model. And the turn's log recorded the first model as the turn's model while the text came from the second, which is the attribution gap v0.8.5's own documentation warns about. What this run does not cover: channels such as Telegram or Slack, the gateway WebSocket, RPC and ACP clients — the transports whose event sinks the no-replay rule is written for — the Anthropic slot, real provider outages, and any request through Kunavo.

Before you re-send: what already ran, and what already billed

ZeroClaw's own tool loop reads the stream to completion, recovers tool calls after it ends, runs them, then opens a fresh streaming call for the next assistant turn. So the tools requested by the iteration that broke have not run — but that is a narrower comfort than it sounds. Provider-side pre-executed tool calls are a separate event class that already had effects upstream, which is precisely why they block replay. And long turns break late: #10736 notes the preceding tool call completed successfully before its failure, and #10787's log shows the break landing on iteration 2 with 126 messages in the request. Re-sending the original prompt replays every earlier side effect the model would repeat.

A clean-looking transcript is not proof either. Issue #9421, open at priority p1 against both the Anthropic and the OpenAI-compatible provider families, is titled that incomplete terminal responses can be reported as successful. On the Code/ACP surface two further open p1 reports describe a failed turn discarding accepted prompts and completed tool exchanges from durable history (#10788) and a budget-exceeded turn losing visible progress after session restore (#10659), with the pull request to persist interrupted turn progress still unmerged. All were open on September 21, 2026 and several are marked in progress, so re-check rather than quote this snapshot.

On cost, v0.8.5 and master genuinely disagree and you should read the one matching your build. The release's doc calls the final record a success notice rather than a canonical ledger of every attempt and says not to infer per-attempt cost accuracy from it; master replaces that paragraph with a per-attempt usage_by_provider ledger from pull request #8966, merged September 18, 2026, which no release contains and which master itself scopes to event-instrumented turn paths. Meanwhile the interrupted-stream usage snapshot is an optional field that can be absent, and ZeroClaw asks OpenAI-compatible endpoints for usage in a final SSE chunk — the one a truncated stream may never send. Treat that last point as a mechanism to check in your own cost output, not as a measured result. Reconcile against the endpoint's own usage record instead; on Kunavo that is the usage log.

Why a gateway in front of a model produces this marker

The most likely third-party cause is a completion signal that never arrives. ZeroClaw's v0.8.5 streaming documentation states that transports do not rely on connection close as the success signal: OpenAI-compatible streams finish on [DONE], OpenAI Responses streams on their terminal response event, and Anthropic streams on message_stop, and servers may keep the HTTP connection open after those events. A stream that closes without its signal is surfaced as an error — SSE stream closed before {completion_signal}: response truncated — rather than as a short success. That is an endpoint defect, not a ZeroClaw one. One exception is documented: the Anthropic parser currently also treats EOF after a non-empty message_delta.stop_reason as complete even without message_stop, and the pull request proposing to require it has not landed on either ref.

The second cause is silence on an open socket. ZeroClaw uses byte-idle timeouts rather than a whole-request deadline, documented as 300 seconds for OpenAI Responses and OpenAI-compatible providers and 90 seconds for Anthropic, with each body read resetting the clock. An endpoint that buffers an upstream response and forwards nothing for a minute and a half trips the Anthropic family slot while surviving the OpenAI-compatible one — worth knowing because an Anthropic Messages endpoint goes on the anthropic slot with a uri override, not on custom. See the Messages base URL doc and OpenAI-compatible API for the two wire protocols.

What a dead turn costs, in illustrative arithmetic

Separate the two bills. The ZeroClaw runtime is $0 — zeroclaw.com states it is open source, dual-licensed MIT OR Apache-2.0, with no subscription and no hosted seat, and that you pay only your own LLM provider costs, or nothing at all running a local model with Ollama. No tier unlocks resume, a larger retry budget or guided recovery, because there is no tier.

The model bill is the one an interruption touches. These figures are token arithmetic on assumptions, not a measured task cost and not a bill ceiling. Assume one turn sending 110,000 uncached input tokens — the prompt size in the single dated overload episode #10787 records, where the upstream accepted the request and ran prefill before shedding it — and receiving 2,000 output tokens before the stream dies. The three-attempt column is provider_retries + 1 at the documented default of 2. Rates are live Kunavo catalog prices per million tokens.

ModelInput / output per 1MOne dead attemptThree attempts
Claude Haiku 4.5$0.70 / $3.50$0.084$0.252
GPT-5.6 Terra$0.70 / $4.20$0.085$0.256
Claude Sonnet 4.6$2.10 / $10.50$0.252$0.756
Claude Opus 5$3.50 / $17.50$0.420$1.260

Whether any given endpoint charges for a request it shed is that endpoint's own billing policy, and nothing in ZeroClaw's source or documentation states it — this page did not measure it for any provider. The arithmetic is here to size the question, not to answer it. Kunavo's catalog amount is a billing floor rather than a cap: when the upstream reports its charge, the bill is the greater of catalog cost and upstream cost times the applicable markup. The minimum top-up is $10 in prepaid credit, a funding minimum rather than a task fee or subscription — see billing details.

Which route holds up best against this failure

RouteHow it behaves on a mid-stream breakWhat you give up
One endpoint, direct vendorA single-candidate reliability configuration, so it sits in #10736's reported population on v0.8.5Nothing about being a first-party vendor changes the walk; one candidate is one candidate
One endpoint, gatewayIdentical single-candidate shape. What a gateway buys here is switching models on one key and one balance, not stream resilienceAn extra hop that can itself close without a completion signal, and ZeroClaw prices it only if you write its [cost.rates] entries yourself
Two or more candidates in the profileThe reliability walk has somewhere to go. In the October 1, 2026 terminal run it recovered after both an early and a mid-reply break — through the second modelA second model or alias to maintain, and a recovered answer that comes from your fallback rather than your first choice
Local model via OllamaA re-send costs time and hardware rather than money, so a conservative retry is cheapThe capability gap against hosted frontier models, and a machine to run one
A flat-rate subscription agentNot a ZeroClaw route at all — the project has no subscription and no hosted seatYou would be changing client, not changing ZeroClaw's recovery behavior

Whichever you pick, the operating rule is the one ZeroClaw already encodes: after [stream interrupted], read the persisted partial, establish what already took effect, then re-send something narrower than the original. Kunavo's configuration references for OpenAI-compatible and Messages-style endpoints are setup documentation rather than a compatibility test — the October 1 run above used a local test server, not Kunavo. Start at the error reference to decode what your endpoint returned, and create a Kunavo account when you are ready to fund a key. OpenRouter vs LiteLLM is the closest comparison for the one-candidate-versus-many decision above.

Frequently asked questions

Does ZeroClaw retry a stream that was interrupted?

It depends entirely on whether you had already seen output. ZeroClaw's provider-routing documentation for the released v0.8.5 says the stream is opened once and entries are not switched after it has started, so nothing is ever resumed — recovery, where it exists, is a brand-new request. If the stream fails before any immutable event output is visible, the documented behavior is that the runtime retries the whole call through the non-streaming path. Once text, reasoning or pre-executed tool events have reached an immutable event sink, the interruption becomes StreamInterruptedAfterOutput and the runtime does not replay the request. That second rule is the same on master. But run on October 1, 2026 in v0.8.5's interactive terminal client, neither rule showed up as written: with one candidate nothing was retried, before or after text appeared, and with a second candidate in fallback_models the turn was re-sent without streaming to that second model in both cases, including after part of the answer had been printed. Channels and the gateway WebSocket were not run. Documentation checked September 21, 2026.

What does [stream interrupted] mean in ZeroClaw?

It is the user-visible marker for a transport stream that died mid-turn, defined in ZeroClaw's English locale file as the Fluent key turn-stream-interrupted and shown across every transport — channels, WS, RPC, ACP and CLI. It is deliberately a different marker from [interrupted by user] and [turn cancelled via client], so seeing this one tells you nobody pressed stop. When the stream dies after visible output, the partial text is persisted as an assistant message with the marker appended, but only when that partial text is non-empty: a turn that produced only reasoning or only pre-executed tool events persists nothing. Non-English installs carry the same key with translated text, so do not grep for the English bracket string on one. Read at release tag v0.8.5 on September 21, 2026. In v0.8.5's interactive terminal client on October 1, 2026, a stream cut mid-reply did not print this marker; the terminal showed a provider-failure error instead.

Is it safe to just re-send the prompt after a ZeroClaw stream interruption?

Not automatically, and ZeroClaw's own maintainers treat it that way. The runtime reads a stream to completion, recovers tool calls after it ends, then runs them — so the tools of the iteration that broke have not run. But a long turn breaks on later iterations too: one upstream report notes the preceding tool call completed successfully before the failure, and another's log shows the break landing on iteration 2 with 126 messages in the request. Anything an earlier iteration already did — a file written, a command run, a message sent — happens again if you re-send the same prompt blind. The open feature request for guided recovery lists its own non-goals as blindly replaying a tool-bearing or approval-bearing turn and treating every provider error as transient. Read the persisted partial text first, check what already took effect, then re-send a narrowed prompt rather than the original.

Can I configure ZeroClaw to resume the broken stream?

No. There is no setting for it in any released version, and no paid tier that unlocks one — ZeroClaw is free and open source, dual-licensed MIT OR Apache-2.0, with no subscription and no hosted seat, so the limit is an engineering boundary rather than a plan boundary. The no-replay-after-visible-output rule is in the source and locked by a regression test whose own failure message reads that a stream error after visible output must fail the turn with no fallback retry — though in v0.8.5's interactive terminal client on October 1, 2026, a profile with a second candidate did re-send after text had been printed, so the rule is not a guarantee on every transport. Guided recovery after an interrupted turn is issue #10634 — open, labelled status:accepted and priority:p2, and routed to needs design or RFC discussion first as of September 21, 2026. Accepted means triage accepted the problem statement, not that code was written or merged.

My log says it is falling back to non-streaming chat and then the turn dies. Why?

On the released v0.8.5 that log line can be untrue. Upstream issue #10736, titled that a pre-output stream failure skips the advertised non-streaming fallback, reports that the runtime logs it is falling back to non-streaming chat but does not send the non-streaming request, and the turn terminates immediately with All model providers/models failed after 0 failure event(s). Its own impact statement names the affected population as users with a single provider candidate, especially configurations with zero retries. Zero retries is not the only case: its reproduction sets provider_retries = 0, but the follow-on issue #10787 reproduces the same immediate failure with provider_retries left at the documented default of 2. The issue closed on September 18, 2026, after v0.8.5 was published on September 5, so no published release contains the fix. It reproduced on v0.8.5 on October 1, 2026: one streaming request, no non-streaming follow-up, and that error — with provider_retries = 2, and whether the stream broke before or after text appeared. Adding a second model under fallback_models was enough for the turn to recover. Debugging this from logs on v0.8.5 means reading a fallback that did not happen.

Was I billed for the interrupted turn, and how do I check?

Check the endpoint's own usage record rather than ZeroClaw's, because v0.8.5's documentation tells you not to trust its per-attempt figure: it describes the final fallback notice as a success notice, not a canonical ledger of every attempt, and says not to infer per-attempt cost accuracy from it. The per-attempt usage_by_provider ledger that resolves this landed on master via pull request #8966, merged September 18, 2026, after v0.8.5 shipped, so it is in no release — and master scopes it to event-instrumented turn paths. ZeroClaw does capture a usage snapshot on an interrupted stream, but the field is optional and can be absent, and it asks OpenAI-compatible endpoints for usage in a final SSE chunk — the chunk a truncated stream may never deliver. That last point is read from the source, not observed at runtime. Separately, ZeroClaw's own cost figures come from the operator-written [cost.rates] rate sheets in your config, so an endpoint you have not priced there is not priced by ZeroClaw either.

Run on October 1, 2026: the v0.8.5 release binary in interactive terminal mode against a local test server that cut the stream — the four rows of the results table; nothing else was run, and no request went to Kunavo. Issue states re-checked the same day (#10787 has since closed; #10634 is still open). Repository source read at release tag v0.8.5, documentation read at the version-pinned /v0.8.5/ path, and issue and pull-request states read on September 21, 2026; several of those issues were marked in progress and can move. Kunavo token rates come from the live catalog, and every dollar figure here is illustrative token arithmetic rather than a measured task cost.