sveltejs/kit · error · HttpError

Invalid query.live response

Error message

Invalid query.live response

What it means

The query.live client expects a streaming (non-JSON) response. If the response content-type is application/json, it parses the body, surfaces any side-channel result, then throws HttpError 500 'Invalid query.live response' because a JSON body cannot be a live stream.

Source

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

	});

	// detect new deployments from the response header
	notify_version(response.headers.get('x-sveltekit-version'));

	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);

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Inspect the server handle hook and exclude/exempt the query.live (event.request url containing __data or the remote endpoint) requests from rewriting/redirecting
  2. Check for redirects triggered for that request (auth redirects) and allow the streaming endpoint through
  3. Check reverse-proxy config so it doesn't replace streaming responses with JSON error pages
  4. Verify the client and server @sveltejs/kit versions match

Example fix

// before
export const handle = async ({ event, resolve }) => {
  if (!event.locals.user) redirect(307, '/login'); // also catches stream requests
  return resolve(event);
};
// after
export const handle = async ({ event, resolve }) => {
  if (!event.locals.user && !event.url.pathname.startsWith('/_app/remote')) {
    redirect(307, '/login');
  }
  return resolve(event);
};
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch(endpoint, { headers: { accept: 'text/event-stream' } });
const ct = res.headers.get('content-type') ?? '';
if (ct.includes('application/json')) throw new Error('endpoint returned JSON, not a stream');

Type guard

const isStreaming = (res) => !(res.headers.get('content-type') ?? '').includes('application/json');

Try / catch

try {
  await query.live(...);
} catch (e) {
  if (e.status === 500 && e.message === 'Invalid query.live response') {
    // check handle hook/redirect/proxy and retry
  } else throw e;
}

Prevention

When it happens

Trigger: The query.live endpoint's response was replaced by a JSON response — commonly because a redirect or handle() hook rewrote the response, or the request hit a normal JSON route/error page instead of the streaming endpoint.

Common situations: Custom server handle hook intercepting and short-circuiting requests; redirect issued inside handle for the streaming request; proxy/gateway returning a JSON error page (auth walls, 502 pages); middleware converting responses to JSON.

Related errors


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