{"record":{"id":"897ddb96d47cbb53","repo":"sveltejs/svelte","slug":"fork-timing","errorCode":"fork_timing","errorMessage":"fork_timing\nCannot create a fork inside an effect or when state changes are pending\nhttps://svelte.dev/e/fork_timing","messagePattern":"fork_timing\nCannot create a fork inside an effect or when state changes are pending\nhttps://svelte\\.dev/e/fork_timing","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/svelte/src/internal/client/errors.js","lineNumber":295,"sourceCode":"\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/fork_discarded`);\n\t}\n}\n\n/**\n * Cannot create a fork inside an effect or when state changes are pending\n * @returns {never}\n */\nexport function fork_timing() {\n\tif (DEV) {\n\t\tconst error = new Error(`fork_timing\\nCannot create a fork inside an effect or when state changes are pending\\nhttps://svelte.dev/e/fork_timing`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/fork_timing`);\n\t}\n}\n\n/**\n * `getAbortSignal()` can only be called inside an effect or derived\n * @returns {never}\n */\nexport function get_abort_signal_outside_reaction() {\n\tif (DEV) {\n\t\tconst error = new Error(`get_abort_signal_outside_reaction\\n\\`getAbortSignal()\\` can only be called inside an effect or derived\\nhttps://svelte.dev/e/get_abort_signal_outside_reaction`);\n\n\t\terror.name = 'Svelte error';\n\n\t\tthrow error;\n\t} else {\n\t\tthrow new Error(`https://svelte.dev/e/get_abort_signal_outside_reaction`);\n\t}\n}","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/sveltejs/svelte/blob/20b341f10048cf1016a2028ac7eee5595cfef6a5/packages/svelte/src/internal/client/errors.js#L277-L313","documentation":"Thrown at reactivity/batch.js:1381 inside fork() when current_batch is non-null at the moment of calling. A fork snapshots the current state graph and must run in a clean (non-flushing) environment; creating one while a batch is mid-flush or while state changes are pending would fork an inconsistent snapshot.","triggerScenarios":"Calling fork() from inside a $effect (which runs during a batch flush), from within another fork's initialiser, or at a moment when a pending state write has not yet been flushed. The guard at batch.js:1380-1382 checks current_batch!==null.","commonSituations":"Speculative navigation forks triggered from within an effect; calling fork() in a reactive callback that fires during update flush; event handlers that fire synchronously during a batched update.","solutions":["Move the fork() call out of any effect — call it from a plain event handler or top-level action that runs when no batch is active.","Defer the fork with queueMicrotask or setTimeout(0) so it runs after the current flush completes.","Restructure so speculative state is computed via $derived rather than forked mid-flush."],"exampleFix":"// before\n$effect(() => {\n  const f = fork(() => { speculative = data(); }); // current_batch active\n});\n\n// after\nfunction navigate() {\n  const f = fork(() => { speculative = data(); }); // called from event, no batch\n  // ...\n}","handlingStrategy":"validation","validationCode":"// Only call fork() from a non-reactive context (event handler, top-level action).\n// Avoid calling fork() from inside $effect/$derived bodies.\n// If unsure, defer:\nfunction safeFork(fn) {\n  queueMicrotask(() => fork(fn));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call fork() from user-triggered event handlers, not from effects.","If a fork must be speculative, trigger it from a plain function invoked outside the reactive flush.","Defer fork creation with queueMicrotask when in doubt about the current batch state."],"tags":["svelte","fork","experimental","async","reactivity","batch"],"backgroundTag":null,"analyzedSha":"20b341f10048cf1016a2028ac7eee5595cfef6a5","analyzedAt":"2026-08-12T23:37:30.399Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}