sveltejs/kit · error

Expected query.live response body to be a ReadableStream

Error message

Expected query.live response body to be a ReadableStream

What it means

After ruling out a JSON body, the client requires response.body to be a ReadableStream to read the live query frames. A null body (e.g. opaque/failed response or an environment without streaming support) makes the client throw this Error.

Source

Thrown at packages/kit/src/runtime/client/remote-functions/query-live/iterator.js:51

	if (!response.ok) {
		/** @type {RemoteFunctionResponse | undefined} */
		const result = await response.json().catch(() => undefined);

		throw result?.type === 'error'
			? new HandledHttpError(result.error)
			: new HttpError({ status: response.status, message: response.statusText });
	}

	if (response.headers.get('content-type')?.includes('application/json')) {
		// we can end up here if we e.g. redirect in `handle`
		const result = await response.json();
		await handle_side_channel_response(result);
		throw new HttpError({ status: 500, message: 'Invalid query.live response' });
	}

	if (!response.body) {
		throw new Error('Expected query.live response body to be a ReadableStream');
	}

	const reader = response.body.getReader();

	try {
		on_connect();

		for await (const node of read_sse(reader)) {
			if (node.type === 'result') {
				yield devalue.parse(node.result, app.decoders);
				continue;
			}

			await handle_side_channel_response(node);
			throw new HttpError({ status: 500, message: 'Invalid query.live response' });
		}
	} finally {
		try {

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Ensure the server endpoint actually streams (SSE/chunked) and returns 200 with a body
  2. Fix CORS so the response is not opaque (proper Access-Control-Allow-Origin, no mode:'no-cors')
  3. Remove/configure proxies that buffer or strip streaming responses
  4. Test in a modern browser/runtime that supports fetch ReadableStream

Example fix

// before
const res = await fetch(url, { mode: 'no-cors' }); // body is null
// after
const res = await fetch(url, { mode: 'cors' }); // streamed body available
Defensive patterns

Strategy: type-guard

Type guard

const hasBody = (res) => res.body instanceof ReadableStream;

Try / catch

try {
  await live.query(...);
} catch (e) {
  if (e.message === 'Expected query.live response body to be a ReadableStream') {
    // fall back to polling a regular query
  } else throw e;
}

Prevention

When it happens

Trigger: The fetch for a query.live endpoint returned a response without a body — e.g. a 204/empty response, an opaque cross-origin no-cors response, or a runtime/proxy that strips the body of streaming responses.

Common situations: Deploying behind a proxy that buffers/strips streaming bodies; CORS misconfiguration yielding opaque responses; unsupported browser/runtime without ReadableStream on fetch responses; server returning an empty status like 204.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/e3e6b946a312fa73. Report an issue: GitHub.