sveltejs/kit · error · HandledHttpError

new HandledHttpError(server_data_node.error) — rethrows serv

Error message

new HandledHttpError(server_data_node.error) — rethrows server-provided error object

What it means

During client-side navigation, if a parent branch's data previously came from a server error node and the parent changed, the client re-throws the server-provided error object as `HandledHttpError` so it flows through the normal error-handling path (nearest `+error.svelte` boundary) instead of re-running the child `load`. It is an internal rethrow of an error already produced on the server.

Source

Thrown at packages/kit/src/runtime/client/client.js:1519

		// reuse data from previous load if it's still valid
		const valid =
			(!server_data_node || server_data_node.type === 'skip') &&
			loader[1] === previous?.loader &&
			!has_changed(
				parent_changed,
				route_changed,
				url_changed,
				search_params_changed,
				previous.universal?.uses,
				params
			);
		if (valid) return previous;

		parent_changed = true;

		if (server_data_node?.type === 'error') {
			// rethrow and catch below
			throw new HandledHttpError(server_data_node.error);
		}

		return load_node({
			loader: loader[1],
			url,
			params,
			route,
			parent: async () => {
				const data = {};
				for (let j = 0; j < i; j += 1) {
					Object.assign(data, (await branch_promises[j])?.data);
				}
				return data;
			},
			server_data_node: create_data_node(
				// server_data_node is undefined if it wasn't reloaded from the server;
				// and if current loader uses server data, we want to reuse previous data.
				server_data_node === undefined && loader[0] ? { type: 'skip' } : (server_data_node ?? null),

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Handle the error in the nearest `+error.svelte` boundary; access it via `page.error` / `error` state
  2. Fix the root cause on the server so the parent load no longer errors (e.g. valid auth, correct data)
  3. In `handleError` hooks, log and shape the server error so the client displays something meaningful

Example fix

// before
// no error boundary -> unhandled HandledHttpError on navigation
// after
// src/routes/+error.svelte
<script>
import { page } from '$app/state';
</script>
<p>{page.error?.message}</p>
Defensive patterns

Strategy: try-catch

Validate before calling

// before navigating, check whether the server data indicated an error
if (branchServerData?.type === 'error') {
  handleError(branchServerData.error);
}

Type guard

const isServerErrorNode = (node) => node?.type === 'error' && node.error != null;

Try / catch

try {
  await navigate(url, { replaceState: false });
} catch (e) {
  if (e instanceof HandledHttpError || e?.status != null) {
    renderErrorBoundary(e);
  } else throw e;
}

Prevention

When it happens

Trigger: Navigating to a route where the server returned `{ type: 'error' }` in the server data node for a parent branch and a subsequent navigation finds `parent_changed` — the stored server error is rethrown for handling.

Common situations: A parent `+layout.server.js` load fails (e.g. auth check) and child routes attempt navigation; handling server errors from a remote form/load result in an error boundary.

Related errors


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