SvelteKit: Cannot access url.searchParams on a page with prerendering enabled
A prerendered page is one file written at build time, so there is no request to read a query string from. The clash usually comes from a layout: prerender was switched on once near the root and inherited by a page that filters or paginates from the URL.
Quick fix
Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.
// Find where it was switched on, which is often not this page
// src/routes/+layout.js
export const prerender = true;
// Turn it off for the page that needs a request
// src/routes/search/+page.js
export const prerender = false;
// Or read the query string in the browser rather than during load
<script>
import { page } from '$app/state';
let q = $derived(page.url.searchParams.get('q') ?? '');
</script>
// Path parameters prerender happily, query strings do not, so make it a route
// /products/[category] rather than /products?category=x
// url.pathname and url.origin are safe while prerendering, searchParams is not
# The build log lists every route it prerendered, which settles the argument
npm run build
How to diagnose Svelte errors
Svelte errors mostly arise at the compiler's boundaries: the $ store prefix only works on real stores in component context, and SvelteKit's load functions run in two different environments with different capabilities. A 500 from a load function usually means server-only code (a database client, a secret, fs) reached a universal load that also runs in the browser.
If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.
- Check whether the file is a universal load (
+page.js) or a server-only load (+page.server.js). Anything touching secrets or the filesystem belongs in the latter. - Read the full server-side stack trace in the terminal, not just the browser's 500 page: SvelteKit hides details in production for security.
- For
$prefix errors, confirm the value is an actual store with asubscribemethod and that you are inside a component, not a plain module. - Use
$env/static/privateand$env/dynamic/privatefor secrets so the compiler enforces the server-only boundary for you. - Reproduce with
vite build && vite preview; dev-mode behaviour differs meaningfully from the production build.
Tools worth reaching for
vite build && vite previewSvelteKit terminal logssvelte-check$env/static/private
Authoritative references
Primary documentation for this error, worth reading before applying any fix in production.
Related Svelte errors
- Svelte 5: `$:` is not allowed in runes mode, use `$derived` or `$effect` insteadAs soon as a component uses any rune ($state, $props, $derived), Svelte compiles the whole…
- Svelte 5: `$effect` can only be used inside an effectEffects have to be created while a component is initialising, so calling `$effect` from a…
- Svelte 5: `$props()` can only be used at the top level of componentsRunes are compiled away rather than called, so `$props()` has to appear exactly once as the…
- Svelte 5: `export let` is not allowed in runes mode, use `$props()` insteadA component is in runes mode, where props arrive through $props() rather than exported let…
- Svelte 5: $state / $derived can only be used inside a .svelte or .svelte.js fileRunes are compiler features, not runtime functions. They only work in files the Svelte…
- Svelte 5: Cannot export state from a module if it is reassignedIn a .svelte.js or .svelte.ts module, $state works because the compiler rewrites every read…
- Svelte 5: effect_update_depth_exceeded (Maximum update depth exceeded)An effect wrote to state that it also reads, so running it schedules it again and Svelte…
- Svelte 5: State referenced in its own scope will never updateReading a `$state` variable into a plain `const`, or passing it to a function, copies the…
Browse other categories
- HTTP 494xx client errors, 5xx server errors, redirects, headers and protocol problems.
- JavaScript 42npm resolution, async pitfalls, hydration, memory limits and runtime type…
- Database 41Connections, deadlocks, constraints, replication and memory limits.
- AI 35Rate limits, context windows, GPU memory and model-serving failures.
- Network 35Refused connections, timeouts, resets, MTU problems and port exhaustion.
- Python 35Imports, virtual environments, encoding, concurrency and dependency conflicts.
- Kubernetes 34CrashLoopBackOff, ImagePullBackOff, OOMKilled, RBAC, scheduling and storage.
- Docker 27Daemon connectivity, disk space, image pulls, ports and architecture mismatches.
- System 26Disk space, systemd units, file descriptors, OOM killer and scheduled jobs.
- Cloud 25IAM permissions, quotas, service limits and credential failures.
- Security 25JWT validation, CSRF, OAuth grants, SELinux, SSH host keys and CSP.
- TLS 24Untrusted authorities, expiry, hostname mismatch, chains and cipher negotiation.
Something missing or wrong?
This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.