sveltejs/kit · error
Cannot used reserved query parameter "${INVALIDATED_PARAM}"
Error message
Cannot used reserved query parameter "${INVALIDATED_PARAM}" What it means
When the client fetches data it appends a reserved query parameter (__invalidated or similar INVALIDATED_PARAM) to communicate which stores need invalidation. If the developer's own URL already contains that parameter, appending it would corrupt the request, so DEV throws. This only guards the dev experience; it indicates the app is colliding with an internal protocol detail.
Source
Thrown at packages/kit/src/runtime/client/client.js:3676
result.props.page.state = history_metadata?.persistState ? parse(history_metadata.state) : {};
}
await initialize(result, target, should_hydrate);
}
/**
* @param {URL} url
* @param {boolean[]} invalid
* @returns {Promise<import('types').ServerNodesResponse | import('types').ServerRedirectNode>}
*/
async function load_data(url, invalid) {
const data_url = new URL(url);
data_url.pathname = add_data_suffix(url.pathname);
if (url.pathname.endsWith('/')) {
data_url.searchParams.append(TRAILING_SLASH_PARAM, '1');
}
if (DEV && url.searchParams.has(INVALIDATED_PARAM)) {
throw new Error(`Cannot used reserved query parameter "${INVALIDATED_PARAM}"`);
}
data_url.searchParams.append(INVALIDATED_PARAM, invalid.map((i) => (i ? '1' : '0')).join(''));
// use window.fetch directly to allow using a 3rd party-patched fetch implementation
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()) };View on GitHub (pinned to 03f1687fe6)
Solutions
- Remove the reserved parameter from URLs before passing to goto/fetch navigation
- Never persist/replay URLs taken from SvelteKit __data requests
- Rename your own query parameter if it collides with the internal key
Example fix
// before
const target = new URL(savedUrl); // contains ?__invalidated=1
await goto(target.href);
// after
const target = new URL(savedUrl);
target.searchParams.delete('__invalidated');
await goto(target.href); Defensive patterns
Strategy: validation
Validate before calling
const RESERVED = '__invalidated'; // internal INVALIDATED_PARAM
function stripReservedParams(u) {
const url = new URL(u, location.href);
url.searchParams.delete(RESERVED);
return url;
}
await goto(stripReservedParams(savedUrl).href); Try / catch
try { await goto(url); } catch (e) { if (e.message.includes('reserved query parameter')) { const u = new URL(url, location.href); [...u.searchParams.keys()].forEach((k) => { if (k.startsWith('__')) u.searchParams.delete(k); }); await goto(u.href); } else { throw e; } } Prevention
- Never reuse URLs captured from __data network requests
- Avoid query params starting with double underscores
- Sanitize persisted deep-link URLs before navigation
When it happens
Trigger: goto('/page?__invalidated=...') or navigating with a hand-built URL containing the reserved key; persisting a data-request URL (with the param) and re-navigating to it.
Common situations: Replaying URLs captured from network tab data-suffix requests; caching full request URLs including internal params; naming custom query params identically to the internal one.
Related errors
- Cannot build with ${JSON.stringify(file)} because Bun treats
- Cannot build with ${JSON.stringify(file)} because Bun treats
- Page options are ignored when `router.type === 'hash'` (${no
- Cannot prerender a route with both +page and +server files (
- Mismatched route config for ${route.id} — the +page and +ser
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/65b307275f19b457.
Report an issue: GitHub.