sveltejs/svelte · error · Error
get_abort_signal_outside_reaction
get_abort_signal_outside_reaction
Error message
get_abort_signal_outside_reaction `getAbortSignal()` can only be called inside an effect or derived https://svelte.dev/e/get_abort_signal_outside_reaction
What it means
Thrown at index-client.js:71 inside getAbortSignal() when active_reaction is null. getAbortSignal returns an AbortController signal tied to the current effect/derived lifecycle so async work is cancelled on re-run or teardown; without an active reaction there is no lifecycle to bind it to.
Source
Thrown at packages/svelte/src/internal/client/errors.js:311
throw error;
} else {
throw new Error(`https://svelte.dev/e/fork_timing`);
}
}
/**
* `getAbortSignal()` can only be called inside an effect or derived
* @returns {never}
*/
export function get_abort_signal_outside_reaction() {
if (DEV) {
const 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`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/get_abort_signal_outside_reaction`);
}
}
/**
* Expected to find a hydratable with key `%key%` during hydration, but did not.
* @param {string} key
* @returns {never}
*/
export function hydratable_missing_but_required(key) {
if (DEV) {
const error = new Error(`hydratable_missing_but_required\nExpected to find a hydratable with key \`${key}\` during hydration, but did not.\nhttps://svelte.dev/e/hydratable_missing_but_required`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/hydratable_missing_but_required`);
}View on GitHub (pinned to 20b341f100)
Solutions
- Call getAbortSignal() only from within a $derived (e.g. `const data = $derived(await getData(id))`) or a $effect.
- Pass the signal down from the effect/derived rather than calling getAbortSignal in a leaf utility.
- If you need cancellation outside reactivity, construct your own AbortController and manage its lifecycle.
Example fix
// before
async function loadData(id) {
const res = await fetch(`/api/${id}`, { signal: getAbortSignal() });
return res.json();
}
// called from a plain event handler — no active reaction
// after — call from a $derived so a reaction is active
const data = $derived(loadData(id));
// loadData now runs inside the derived, getAbortSignal has a reaction Defensive patterns
Strategy: validation
Validate before calling
// Only call getAbortSignal() from inside a $derived or $effect.
// For utilities, accept an explicit signal argument instead:
async function loadData(id, signal) {
const res = await fetch(`/api/${id}`, { signal });
return res.json();
}
// caller: const data = $derived(loadData(id, getAbortSignal())); Prevention
- Call getAbortSignal() only from within a $derived or $effect body.
- Pass signals explicitly to leaf utilities rather than calling the rune there.
- Outside reactivity, manage your own AbortController.
When it happens
Trigger: Calling getAbortSignal() in module scope, in a plain function not invoked from an effect/derived, in an event handler, or after the component finished initialising. The guard at index-client.js:70-72 checks active_reaction===null.
Common situations: Calling getAbortSignal() inside a plain async utility imported from a .js file; using it in an onMount-style function that runs outside a derived; refactoring data fetching out of a $derived into a plain function.
Related errors
- async_derived_orphan
- effect_in_unowned_derived
- effect_orphan
- effect_pending_outside_reaction
- effect_update_depth_exceeded
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/36cbae547f736364.
Report an issue: GitHub.