cube-js/cube · error
No response body available for streaming
Error message
No response body available for streaming
What it means
After a successful (response.ok) fetch in HttpTransport.requestStream(), the code checks that a readable body exists before streaming chunks via responseChunks(response). If response.body is null/undefined, it throws 'No response body available for streaming'. This happens in environments whose fetch implementation does not expose a streaming ReadableStream body.
Source
Thrown at packages/cubejs-client-core/src/HttpTransport.ts:244
stream: async () => {
const response = await fetch(url, {
method: requestMethod,
headers: {
Authorization: this.authorization,
'x-request-id': baseRequestId || 'stream-request',
...this.headers,
} as HeadersInit,
credentials: this.credentials,
body: requestMethod === 'POST' ? JSON.stringify(params || {}) : null,
signal: actualSignal,
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
if (!response.body) {
throw new Error('No response body available for streaming');
}
return responseChunks(response);
},
unsubscribe: async () => {
if (controller) {
controller.abort();
}
},
};
}
}
export default HttpTransport;
View on GitHub (pinned to 7d981676b3)
Solutions
- Run in an environment whose fetch supports ReadableStream bodies (modern browser, or polyfill with web-streams-polyfill / node-fetch v3+).
- If the runtime cannot support streaming, use the non-streaming load() method instead of stream().
- In tests, make the fetch stub return a real Response with a body (e.g. new Response(JSON.stringify(data))).
- Check for a service worker or no-cors request mode stripping the body; adjust the interceptor or use cors mode.
Example fix
// before (unsupported runtime)
for await (const row of cubeApi.stream(query)) { ... } // throws 'No response body available for streaming'
// after (fallback to non-streaming load)
try {
for await (const row of cubeApi.stream(query)) { ... }
} catch (e) {
if (e.message.includes('No response body available')) {
const resultSet = await cubeApi.load(query);
const rows = resultSet.tablePivot();
} else { throw e; }
} Defensive patterns
Strategy: fallback
Validate before calling
// Feature-detect streaming support before using stream() const supportsStreaming = typeof Response !== 'undefined' && new Response(new ReadableStream()).body instanceof ReadableStream; const fetchRows = supportsStreaming ? () => cubeApi.stream(query) : () => cubeApi.load(query);
Type guard
function hasStreamBody(res: Response): res is Response & { body: ReadableStream } {
return res.body != null && typeof res.body.getReader === 'function';
} Try / catch
try {
for await (const row of cubeApi.stream(query)) { handle(row); }
} catch (e) {
if (e.message.includes('No response body available for streaming')) {
const rs = await cubeApi.load(query); // non-streaming fallback
handleBatch(rs.tablePivot());
} else { throw e; }
} Prevention
- Feature-detect Response.body streaming support once at startup and choose stream() vs load().
- Avoid fetch polyfills on streaming code paths; use native fetch on modern browsers only.
- In tests, stub fetch with real Response objects: new Response(JSON.stringify(data)).
- Audit service workers / interceptors that might strip or replace response bodies.
- On React Native or other runtimes without stream bodies, use load() directly.
When it happens
Trigger: Calling requestStream/cubeApi.stream() in a runtime where the Response from fetch has no .body ReadableStream: browsers without the streams API, apps using a fetch polyfill (whatwg-fetch), old Node fetch without streaming, stubbed fetch in tests returning { ok: true } without a body, or responses through service-worker/opaque (no-cors) handling that strip the body.
Common situations: Legacy browser targets with polyfilled fetch; React Native where fetch lacks response.body streams; jsdom/happy-dom tests with a stubbed fetch; a service worker intercepting and returning a body-less Response.
Related errors
- HTTP ${response.status}: ${response.statusText}
- options.stream must be a function
- unexpected response ${response.statusText}
- Driver's .streamQuery() method is not implemented yet.
- Unexpected stream end before row with names
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/aabfada3cc18651f.
Report an issue: GitHub.