unslothai/unsloth · error · StreamInterruptedError
Response interrupted: the connection dropped before the mode
Error message
Response interrupted: the connection dropped before the model finished. Use Retry to regenerate.
What it means
StreamInterruptedError is thrown when the SSE reader hits EOF (done === true) without ever seeing a terminal signal — neither the [DONE] sentinel nor a chunk with a finish_reason. The connection closed mid-generation, so the partial transcript is incomplete. The message directs the user to Retry to regenerate.
Source
Thrown at studio/frontend/src/features/chat/api/chat-api.ts:1346
let sawReasoningContent = false;
const throwIfReasoningOnlyLength = () => {
if (
terminalFinishReason === "length" &&
sawReasoningContent &&
!sawAssistantContent
) {
throw new GenerationLengthError();
}
};
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
completed = true;
if (!sawTerminalSignal) {
throw new StreamInterruptedError();
}
throwIfReasoningOnlyLength();
break;
}
buffer += decoder.decode(value, { stream: true });
let separatorIndex = buffer.search(/\r?\n\r?\n/);
while (separatorIndex >= 0) {
const rawEvent = buffer.slice(0, separatorIndex);
const separatorLength = buffer[separatorIndex] === "\r" ? 4 : 2;
buffer = buffer.slice(separatorIndex + separatorLength);
const dataLines = parseSseEvent(rawEvent);
if (dataLines.length === 0) {
separatorIndex = buffer.search(/\r?\n\r?\n/);
continue;
}View on GitHub (pinned to 203007d190)
Solutions
- Retry the generation — the UI Retry action re-issues the request.
- Raise intermediary timeouts (proxy_read_timeout, LB idle timeout) for /v1/chat/completions.
- If it reproduces consistently at the same elapsed time, find and raise the timeout that matches that duration.
- Check inference-server logs for OOM/crash mid-generation.
Defensive patterns
Strategy: retry
Type guard
export function isStreamInterruptedError(e: unknown): e is StreamInterruptedError {
return e instanceof StreamInterruptedError;
} Try / catch
try { for await (const c of stream) render(c); }
catch (e) {
if (isStreamInterruptedError(e) && attempt < 2) { await backoff(attempt); return regenerate(); }
throw e;
} Prevention
- Raise proxy/LB idle timeouts above worst-case generation time.
- Keep a Retry affordance on partial transcripts so users self-heal.
- Persist partial output before discarding, so a drop is not data loss.
When it happens
Trigger: Network drop, proxy timeout, server crash, or load-balancer idle kill between chunks: reader.read() resolves done=true with sawTerminalSignal still false.
Common situations: Long generations exceeding proxy/gateway timeouts (nginx proxy_read_timeout, ALB idle timeout); flaky mobile connections; inference server OOM or restart mid-stream; VPN reconnects.
Related errors
- ChatGPT stream ended before completion.
- {path}: not valid JSON: {exc}
- Could not reach ChatGPT authentication.
- ChatGPT returned a malformed stream.
- GraphQL failed after {max_retries} retries: {last_err}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/6d363dd2ea25a0ca.
Report an issue: GitHub.