Hmbown/CodeWhale · error
SSE stream idle timeout after {}s — no data received (bytes_
Error message
SSE stream idle timeout after {}s — no data received (bytes_received={}, stream_age_ms={}, ms_since_last_chunk={}) What it means
A Responses-API SSE stream went quiet for longer than the configured idle timeout (stream_chunk_timeout_secs, default 123s). The streaming loop in crates/tui/src/client/responses.rs:244 wraps every byte_stream.next() poll in tokio::time::timeout; on Elapsed it emits a diagnostic with bytes_received, total stream age, and ms since the last chunk, then aborts the stream.
Source
Thrown at crates/tui/src/client/responses.rs:244
let mut buffer: Vec<u8> = Vec::new();
let mut done = false;
let mut content_block_counter: u32 = 0;
let stream_start = std::time::Instant::now();
let mut last_chunk_at = std::time::Instant::now();
let mut bytes_received: usize = 0;
tokio::pin!(byte_stream);
while !done {
let chunk = match tokio::time::timeout(stream_idle_timeout, byte_stream.next()).await {
Ok(Some(Ok(chunk))) => chunk,
Ok(Some(Err(e))) => {
yield Err(anyhow::anyhow!("Stream read error: {e}"));
return;
}
Ok(None) => break,
Err(_) => {
yield Err(anyhow::anyhow!(super::stream_entry::idle_timeout_message(
stream_idle_timeout,
bytes_received,
stream_start.elapsed(),
last_chunk_at.elapsed(),
)));
return;
}
};
bytes_received += chunk.len();
last_chunk_at = std::time::Instant::now();
buffer.extend_from_slice(&chunk);
// Process complete SSE lines.
loop {
let line = match super::take_sse_line(&mut buffer) {
Ok(Some(line)) => line,
Ok(None) => break,View on GitHub (pinned to 8880682c63)
Solutions
- Retry the request - the stream is already aborted and nothing partial is kept
- Raise the idle budget: add stream_chunk_timeout_secs = 300 under [network] in the config file
- Check intermediaries (nginx, Cloudflare, corporate proxies) for buffering or shorter timeouts on event-stream routes and disable buffering for text/event-stream
- If bytes_received=0 on every attempt, reproduce with curl -N against the same endpoint to confirm the provider actually streams
- Check the provider status page for degraded streaming capacity
Example fix
# config.toml - before [network] # idle budget defaults to 123s # config.toml - after [network] stream_chunk_timeout_secs = 300
Defensive patterns
Strategy: retry
Validate before calling
// Rust caller: budget the stream before starting let idle = Duration::from_secs(cfg.stream_chunk_timeout_secs()); // >= 123s default assert!(idle.as_secs() >= expected_time_to_first_token(&model), "idle budget below TTFT estimate");
Try / catch
// Match on the message prefix; only retry when nothing was consumed or the call is idempotent
let mut attempt = 0;
loop {
match run_streaming_call().await {
Ok(v) => break v,
Err(e) if e.to_string().starts_with("SSE stream idle timeout") && attempt < 2 => {
attempt += 1;
tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
}
Err(e) => return Err(e),
}
} Prevention
- Size stream_chunk_timeout_secs above the provider's worst-case time-to-first-token
- Disable proxy buffering and shorten intermediate timeouts on text/event-stream routes
- Watch bytes_received in the message: 0 means connect-level stall, >0 means mid-stream stall
When it happens
Trigger: Headers succeeded but the body never starts (bytes_received=0), or chunks stop arriving mid-response for > stream_chunk_timeout_secs: server-side generation with no SSE keep-alive comments, a proxy/middlebox that buffers text/event-stream, a half-open TCP connection after a network switch, or an overloaded gateway that accepted the connection then queued indefinitely.
Common situations: Long tool-heavy generations where the provider thinks silently for minutes; VPN or corporate proxy drops; self-hosted vllm/sglang gateways that are slow to first token; default 123s budget left unchanged on a slow endpoint.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- SSE stream idle timeout after {}s — no data received (bytes_
- Stream read error: {e}
- SSE stream idle timeout after {}s — no data received (bytes_
- SSE stream idle timeout after {}s — no data received (bytes_
- Stream read error: {e}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/0559dbcbfdc15857.
Report an issue: GitHub.