{"record":{"id":"14748c4974983965","repo":"sveltejs/kit","slug":"cannot-call-caller-before-router-is-initia","errorCode":null,"errorMessage":"Cannot call ${caller}(...) before router is initialized","messagePattern":"Cannot call (.+?)\\(\\.\\.\\.\\) before router is initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/kit/src/runtime/client/client.js","lineNumber":2968,"sourceCode":"\t\tintent,\n\t\tstate,\n\t\t{ replace: true, persist_state: false, reset: false },\n\t\t'replaceState'\n\t);\n}\n\n/**\n * @param {NavigationIntent} intent\n * @param {App.PageState} state\n * @param {{ replace: boolean; persist_state: boolean; reset: boolean; }} options\n * @param {'goto' | 'pushState' | 'replaceState'} caller\n */\nasync function update_state(intent, state, { replace, persist_state, reset }, caller) {\n\tconst url = intent.url;\n\tconst previous_snapshot_registrations = current_registrations();\n\n\tif (DEV && !started) {\n\t\tthrow new Error(`Cannot call ${caller}(...) before router is initialized`);\n\t}\n\n\tconst nav =\n\t\t// For backwards compatibility we don't trigger navigation hooks etc for push/replaceState\n\t\tcaller === 'goto' ? _before_navigate({ url, type: 'goto', intent, shallow: true }) : undefined;\n\n\tif (!nav && caller === 'goto') return;\n\n\tconst nav_token = {};\n\n\tif (nav) {\n\t\tnavigation_token = invalidation_token = nav_token;\n\t\tis_navigating = true;\n\t\tset_navigation(nav.navigation);\n\t\tupdating = true;\n\t}\n\n\tif (replace) {","sourceCodeStart":2950,"sourceCodeEnd":2986,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/client/client.js#L2950-L2986","documentation":"update_state() backs goto(), pushState() and replaceState(). If the router has not started yet (the `started` flag is false, DEV only), calling any of these throws because there is no router state to update. Navigation APIs are only valid after hydration/initialization completes.","triggerScenarios":"Calling goto/pushState/replaceState at module top level of a +page.svelte or in a store initializer that runs before the client router starts; calling during SSR-adjacent early module evaluation.","commonSituations":"Top-level side effects in components; initializing state from a URL in module scope; invoking navigation from imported module bodies rather than lifecycle callbacks.","solutions":["Move the call into onMount or after the app/router has started","Use $app/stores page state instead of navigating during init","Gate the call on the router being ready (e.g. afterMount flag)"],"exampleFix":"// before\n// +page.svelte module scope\nconst id = page.params.id;\nif (!id) goto('/');\n// after\nimport { onMount } from 'svelte';\nonMount(() => { if (!page.params.id) goto('/'); });","handlingStrategy":"validation","validationCode":"let routerReady = false;\n// set routerReady = true in onMount of your root layout\nfunction safeGoto(...args) {\n  if (!routerReady) return;\n  return goto(...args);\n}","typeGuard":null,"tryCatchPattern":"try { await goto('/'); } catch (e) { if (e.message.includes('before router is initialized')) { /* defer */ } else { throw e; } }","preventionTips":["Never navigate at module top level","Defer navigation to onMount or event handlers","Guard redirects-from-init logic with a readiness flag"],"tags":["navigation","lifecycle","initialization"],"backgroundTag":"router-not-initialized","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}