danielmiessler/Fabric · error · ChatError
STREAM_CONTENT_ERROR
STREAM_CONTENT_ERROR
Error message
value.content
What it means
While consuming the /api/chat stream, a chunk with { type: 'error', content } makes the reader throw ChatError(content, 'STREAM_CONTENT_ERROR'). The HTTP layer was fine; the backend reported an error mid-stream — typically a failure calling the upstream LLM provider after headers were already sent.
Source
Thrown at web/src/lib/services/ChatService.ts:291
): Promise<ReadableStream<StreamResponse>> {
const request = await this.createChatRequest(userInput, systemPromptText);
return this.fetchStream(request);
}
public async processStream(
stream: ReadableStream<StreamResponse>,
onContent: (content: string, response?: StreamResponse) => void,
onError: (error: Error) => void,
): Promise<void> {
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
if (value.type === "error") {
throw new ChatError(value.content, "STREAM_CONTENT_ERROR");
}
if (value.type === "content") {
onContent(value.content, value);
}
}
} catch (error) {
onError(
error instanceof ChatError
? error
: new ChatError("Stream processing error", "STREAM_ERROR", error),
);
} finally {
reader.releaseLock();
}
}
}
View on GitHub (pinned to 338b89cfe9)
Solutions
- Log the value.content of the error event — it carries the backend's upstream error text
- If rate-limit/timeout related, add retry with backoff for streams that fail after partial output
- Reduce context size or split the request if the upstream rejects it mid-generation
Defensive patterns
Strategy: try-catch
Type guard
function isStreamContentError(e: unknown): e is ChatError & { code: 'STREAM_CONTENT_ERROR' } {
return e instanceof ChatError && e.code === 'STREAM_CONTENT_ERROR';
} Try / catch
try {
await chatService.processStream(stream, onContent, onError);
} catch (e) {
if (isStreamContentError(e)) {
keepPartialOutput(); // content already delivered is still valid
showStreamErrorMessage(e.message);
} else throw e;
} Prevention
- Preserve partial assistant output when a stream dies mid-flight
- Show the backend's error event text to the user — it names the upstream cause
- Cap context size to reduce mid-generation provider failures
When it happens
Trigger: Long generations where the vendor API disconnects or rate-limits after the stream began; model context overflow surfacing mid-stream; provider timeout after first tokens; backend panic serialized as an error event.
Common situations: Ollama model OOM-ing on large contexts; API rate limit hit mid-generation; network drop between backend and LLM vendor while the browser-backend connection stays open.
Related errors
AI-assisted analysis of danielmiessler/Fabric@338b89cfe9 (2026-08-15).
Data as JSON: /api/errors/7a0e39b699e582e6.
Report an issue: GitHub.