sveltejs/kit · error

Live query completed before yielding a value

Error message

Live query completed before yielding a value

What it means

A query.live generator must yield at least one value before completing. If the server-side async generator returns (done: true) before the client has received its first value and the query was never ready, SvelteKit throws because there is no value to expose to consumers.

Solutions

  1. Ensure the server generator always yields an initial value before any early return
  2. Check the generator body for early returns/throws before the first yield
  3. Wrap generator logic so reconnects still yield the current value
  4. Log server-side to confirm the generator body actually runs

Example fix

// before
export async function *live() {
  if (!ready) return; // completes without yielding
  yield getData();
}
// after
export async function *live() {
  yield getData(); // always yield at least once
  while (ready) {
    await changes.next();
    yield getData();
  }
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await liveQuery.current;
} catch (e) {
  if (e.message === 'Live query completed before yielding a value') {
    // fall back to a regular query or show empty state
  } else throw e;
}

Prevention

When it happens

Trigger: A live query's server generator returns immediately (e.g. an early return, an unhandled condition, or a reconnect handler that returns without yielding) so the client's generator.next() resolves done while #ready is still false.

Common situations: Server generator whose first statement is a conditional return; generator that only yields after an event that never fires; reconnect logic that returns early when no data has changed yet; abrupt completion due to an error swallowed upstream.

Related errors


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

Appendix: source

Thrown at packages/kit/src/runtime/client/remote-functions/query-live/instance.svelte.js:148

			this.#interrupt = () => {
				controller.abort();
				return stopped;
			};

			const generator = create_live_iterator(this.#id, this.#payload, controller, () => {
				this.#connected = true;
				this.#attempt = 0;
				connected = true;
				on_connect();
			});

			try {
				const { done, value } = await generator.next();

				if (done) {
					if (!this.#ready) {
						throw new Error('Live query completed before yielding a value');
					}
					// stream completed without yielding (e.g. the generator returned
					// immediately on reconnect) — keep the last good value
					this.#done = true;
					this.#fan_out.done();
					break;
				}

				this.set(value);

				for await (const value of generator) {
					this.set(value);
				}

				this.#done = true;
				this.#fan_out.done();
			} catch (error) {
				if (controller.signal.aborted) break;

View on GitHub (pinned to 03f1687fe6)