{"record":{"id":"8daac956073b363a","repo":"Hmbown/CodeWhale","slug":"sse-stream-idle-timeout-after-idle-secs-s-no-data-received-8daac9","errorCode":null,"errorMessage":"SSE stream idle timeout after {idle_secs}s — no data received (bytes_received={bytes}, stream_age_ms={age}, ms_since_last_chunk={since})","messagePattern":"SSE stream idle timeout after (.+?)s — no data received \\(bytes_received=(.+?), stream_age_ms=(.+?), ms_since_last_chunk=(.+?)\\)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client/responses.rs","lineNumber":282,"sourceCode":"            let mut bytes_received: usize = 0;\n\n            tokio::pin!(byte_stream);\n\n            while !done {\n                if !ended {\n                    match tokio::time::timeout(stream_idle_timeout, byte_stream.next()).await {\n                        Ok(Some(Ok(chunk))) => {\n                            bytes_received += chunk.len();\n                            last_chunk_at = std::time::Instant::now();\n                            buffer.extend_from_slice(&chunk);\n                        }\n                        Ok(Some(Err(e))) => {\n                            yield Err(anyhow::anyhow!(\"Stream read error: {e}\"));\n                            return;\n                        }\n                        Ok(None) => ended = true,\n                        Err(_) => {\n                            yield Err(anyhow::anyhow!(super::stream_entry::idle_timeout_message(\n                                stream_idle_timeout,\n                                bytes_received,\n                                stream_start.elapsed(),\n                                last_chunk_at.elapsed(),\n                            )));\n                            return;\n                        }\n                    }\n                }\n\n                // Process complete SSE lines, and the unterminated tail at stream end.\n                loop {\n                    let line = match next_sse_line(&mut buffer, ended) {\n                        Ok(Some(line)) => line,\n                        Ok(None) => break,\n                        Err(err) => {\n                            yield Err(anyhow::anyhow!(\"{err}\"));\n                            return;","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/client/responses.rs#L264-L300","documentation":"The Responses API stream received no data at all from the server for longer than the configured idle timeout (`stream_idle_timeout`). The `select!` branch on the read future timed out, and the handler yields a diagnostic message (built by `idle_timeout_message`) that includes bytes received, stream age, and time since the last chunk, then aborts. This prevents hanging forever on a stalled connection.","triggerScenarios":"The server accepts the request but sends no bytes within `stream_idle_timeout` seconds; the connection stalls mid-stream after some chunks (diagnostics show bytes_received > 0); a hung upstream behind a proxy that keeps the socket open but forwards nothing.","commonSituations":"Provider outages where the endpoint accepts connections but never streams; overloaded self-hosted inference servers queuing requests; misconfigured keepalive behind load balancers; extremely long time-to-first-token on large prompts.","solutions":["Retry the request; stalls are often transient provider-side load","Increase the stream idle timeout configuration if the model legitimately has long silent periods","Check provider status / self-hosted server logs for the stall cause","Confirm no proxy is buffering the SSE response (buffering proxies suppress chunk delivery)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"SSE stream idle timeout\") => {\n        let diag = e.to_string(); // parse bytes_received/ms_since_last_chunk for diagnosis\n        retry_with_backoff();\n    }\n    other => other,\n}","preventionTips":["Set the idle timeout above the endpoint's realistic time-to-first-token","Ensure proxies forward SSE chunks without buffering","Alert on provider stalls via the bytes_received/ms_since_last_chunk diagnostics","Retry stalled streams automatically"],"tags":["network","timeout","streaming","sse"],"backgroundTag":"request-timeout","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}