apache/answer · error
ReadableStream not supported
Error message
ReadableStream not supported
What it means
requestAi throws this when the browser's fetch Response body is not a ReadableStream, i.e. response.body?.getReader() returns undefined. The AI streaming feature depends on the Streams API to consume the response incrementally.
Source
Thrown at ui/src/utils/requestAi.ts:224
method: 'POST',
signal: combinedSignal,
headers: {
Authorization: token,
'Accept-Language': lang,
'Content-Type': 'application/json',
...options.headers,
},
});
// unified error handling (based on request.ts logic)
if (!response.ok) {
await handleHttpError(response, options);
return;
}
const reader = response.body?.getReader();
if (!reader) {
throw new Error('ReadableStream not supported');
}
// store the current reader so it can be cancelled later
requestState.currentReader = reader;
const decoder = new TextDecoder();
let buffer = '';
const processStream = async (): Promise<void> => {
try {
const { value, done } = await reader.read();
if (done) {
options.onComplete?.();
requestState.isProcessing = false;
requestState.currentReader = null;
return;
}View on GitHub (pinned to 3b9f137061)
Solutions
- Upgrade to a browser that supports ReadableStream (all modern evergreen browsers, Safari 10.1+).
- Check that fetch is native, not polyfilled; remove or upgrade the fetch polyfill for this call path.
- Serve the app over HTTPS/modern context if targeting browsers that gate streams on secure contexts.
- Add an explicit feature check before calling requestAi and fall back to a non-streaming request path.
Example fix
// before
const reader = response.body?.getReader();
if (!reader) {
throw new Error('ReadableStream not supported');
}
// after
if (typeof response.body?.getReader !== 'function') {
const text = await response.text(); // non-streaming fallback
return handleFullText(text);
}
const reader = response.body.getReader(); Defensive patterns
Strategy: type-guard
Validate before calling
const supportsStreams = typeof Response !== 'undefined' && new Response().body?.getReader instanceof Function;
Type guard
function hasReadableStream(res: Response): res is Response & { body: ReadableStream } {
return !!res.body && typeof res.body.getReader === 'function';
} Try / catch
try {
await requestAi(params);
} catch (e) {
if (e instanceof Error && e.message === 'ReadableStream not supported') {
await requestAiNonStreaming(params); // fallback path
} else throw e;
} Prevention
- Feature-check ReadableStream once at app startup and disable streaming UI when unsupported
- Avoid fetch polyfills that don't expose Response.body
- Test in target browsers/webviews before shipping streaming features
- Serve over HTTPS where secure-context gating applies
When it happens
Trigger: Calling requestAi (streaming mode) in an environment where Response.body is null or lacks getReader(): old browsers without ReadableStream support, non-HTTPS contexts in some browsers, or certain polyfilled/undici-like fetch implementations that return null bodies.
Common situations: Running the app in legacy browsers (older Safari/IE-based webviews), embedding the UI in an old WebView, using a fetch polyfill that strips the body stream, or service-worker/proxy layers that buffer the response so body.getReader is unavailable.
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/506645d6ff0c4ab5.
Report an issue: GitHub.