sveltejs/kit · error · HandledHttpError
new HandledHttpError({ status: res.status, message: from JSO
Error message
new HandledHttpError({ status: res.status, message: from JSON body, or 'Internal Error' / 'Not Found' for 404 }) What it means
When a server data request fails, the client reads the JSON error body and throws a HandledHttpError whose status comes from the response and whose message comes from the body — falling back to 'Internal Error', or 'Not Found' for 404. This surfaces server-side +error/+server.js failures to calling code such as load functions or streamed data consumers.
Source
Thrown at packages/kit/src/runtime/client/client.js:3699
const fetcher = DEV ? dev_fetch : window.fetch;
const res = await fetcher(data_url.href, {});
// detect new deployments from the response header
notify_version(res.headers.get('x-sveltekit-version'));
if (!res.ok) {
// if `__data.json` doesn't exist or the server has an internal error,
// avoid parsing the HTML error page as a JSON
/** @type {App.Error} */
let error = { status: res.status, message: 'Internal Error' };
if (res.headers.get('content-type')?.includes('application/json')) {
error = { status: res.status, ...(await res.json()) };
} else if (res.status === 404) {
error.message = 'Not Found';
}
throw new HandledHttpError(error);
}
return new Promise((resolve, reject) => {
process_stream(resolve, res).catch(reject);
});
// TODO edge case handling necessary? stream() read fails?
}
/**
* @param {(value: ServerNodesResponse | ServerRedirectNode) => void} resolve
* @param {Response} res
* @returns {Promise<void>}
*/
async function process_stream(resolve, res) {
const reader = /** @type {ReadableStream<Uint8Array>} */ (res.body).getReader();
/**View on GitHub (pinned to 03f1687fe6)
Solutions
- Fix the underlying server endpoint that returned the non-OK status
- Add proper error handling in +server.js/+page.server.js and return typed fails
- Inspect res.status in the HandledHttpError to distinguish 404 vs 500 causes
- Ensure error responses are JSON so meaningful messages reach the client
Example fix
// before
const data = await fetch('/api/items').then((r) => r.json()); // throws HandledHttpError on 500
// after
try {
const data = await fetch('/api/items').then((r) => r.json());
} catch (e) {
console.error(e.status, e.message); // e.g. 404 'Not Found'
return fallback;
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: verify endpoint exists (dev-time check)
async function assertEndpoint(url) {
const r = await fetch(url, { method: 'HEAD' });
if (!r.ok) console.warn(`${url} -> ${r.status}`);
} Type guard
function isHandledHttpError(e) { return e instanceof Error && typeof e.status === 'number'; } Try / catch
try { const data = await loadThing(); } catch (e) {
if (typeof e.status === 'number') {
if (e.status === 404) showNotFound();
else showServerError(e.status, e.message);
} else { throw e; }
} Prevention
- Wrap data fetches in try/catch and branch on e.status
- Return JSON errors from +server.js so messages survive to the client
- Add smoke tests hitting every API route to catch 404/500s early
When it happens
Trigger: A __data fetch (or stream resource fetch) responds non-OK: a 404 from a missing endpoint, a 500 from a throwing +server.js handler; non-JSON bodies fall back to fixed messages.
Common situations: Endpoint removed or route renamed after deploy; unhandled exceptions in form actions/API routes; API returning HTML error pages (no JSON) so message becomes generic 'Internal Error'.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- read(...) failed: could not fetch ${url} (${response.status}
- read(...) failed: could not fetch ${url} (${response.status}
- Address header was specified with ${env_prefix + 'ADDRESS_HE
- ${env_prefix + 'XFF_DEPTH'} must be a positive integer
- ${env_prefix + 'XFF_DEPTH'} is ${xff_depth}, but only found
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/a6adeb84ca5ebf34.
Report an issue: GitHub.