Mid-stream Chutes transport failures are unrecoverable and often untyped (error decoding response body)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- rust
- Domain
- backend-api-design, stream-processing
Research direction
Start with crates/inference_providers/src/attested/chutes/mod.rs:1516, then trace sse_error_frame() in crates/api/src/routes/completions.rs and retry_with_fallback_caps in crates/services/src/inference_provider_pool/mod.rs. Compare the four proposed handling options against the three observed failure shapes and existing pre-stream retry behavior. Done requires a decided, testable approach for mid-stream transport failures rather than an unresolved design discussion.
Written by the indexing model from the issue text.
Description
Summary
When the Chutes upstream byte stream breaks after cloud-api has returned HTTP 200 and started forwarding chunks, the client gets a dead partial stream with nothing actionable, and nothing retries or recovers. This is the one remaining unfixed item from the BeeZi feedback report (2026-07-08, #private-inference): their captured error chunk
{"error":{"message":"Failed to perform completion: Chutes stream transport: error decoding response body","type":"server_error"}}
Where it comes from
crates/inference_providers/src/attested/chutes/mod.rs:1516(line as of24eeb176) wraps reqwest byte-stream errors asCompletionError::CompletionError("Chutes stream transport: {e}");"error decoding response body"is reqwest's Display for a body cut mid-read.sse_error_frame()incrates/api/src/routes/completions.rsserializes it with typeserver_error, then the stream ends with[DONE].retry_with_fallback_capsincrates/services/src/inference_provider_pool/mod.rswraps only stream establishment.classify_retry_decisioneven marksdecoding response bodyas a retryable connection keyword — but that classification never runs once chunks have been emitted, because the 200 + partial output are already committed to the client.- The June–July Chutes PRs (#798, #810, #860, #866, #870) are all pre-stream fallback/retry/observability or chunk cosmetics; #866 made pre-stream transport failures retryable 503s and explicitly left the mid-stream wrap untouched.
Evidence it fires in prod today (post prod-20260716-24eeb17)
- Live repro 2026-07-20: 3 of 15 streaming attempts broke mid-stream on
deepseek/deepseek-v3.2(0/3 onz-ai/glm-5, 0/3 onmoonshotai/kimi-k2.5, 0/36 onminimax/minimax-m2.5incl. 24 at 4-way concurrency — so currently model-concentrated, not path-wide). - The three observed failure shapes, in order of decreasing client ergonomics:
- structured in-stream
server_errorchunk followed by[DONE](the BeeZi capture); - abrupt TCP/chunked-encoding cut — no error chunk, no
[DONE]; - silent stall until the client's own read timeout (120s+ of nothing).
- structured in-stream
- Datadog (us3): 10
Completion stream errorevents witherror_type=completion_errorondeepseek/deepseek-v3.2on 2026-07-18/19, i.e. after the current release was deployed.
Options to discuss
- Retry before first forwarded chunk: if the upstream stream dies after establishment but before any content chunk has been forwarded to the client, the request is still transparently retryable (same semantics as the existing pre-stream retry). Probably the highest-value/lowest-risk slice, but requires moving the retry boundary out of the pool or making the forwarding layer retry-aware.
- Typed + actionable terminal error frame: distinguish
upstream_transport_errorfrom genericserver_error, and include aretryable: truehint, so agent platforms can implement client-side resume-by-retry. - Truncation marker on shape (2)/(3): when the upstream disconnects cleanly without
finish_reason, emit an explicit error/incomplete frame instead of appending a bare[DONE](today silent truncation is indistinguishable from a normal end of stream except by the missingfinish_reason). - Full mid-stream resume (re-prompt with partial output) — probably not worth the complexity.
Raw repro data and per-attempt logs are available from the 2026-07-20 triage session if useful.
- Dominant language
- Rust
- Stars
- 8
- Forks
- 8
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 36
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nearai/cloud-api
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
All issues in nearai/cloud-api
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100