sveltejs/svelte · error · Error
state_unsafe_mutation
state_unsafe_mutation
Error message
state_unsafe_mutation Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state` https://svelte.dev/e/state_unsafe_mutation
What it means
Thrown at reactivity/sources.js:162 in the set() function when writing to a $state source while active_reaction is a DERIVED, BLOCK_EFFECT (template/branch), ASYNC, or EAGER_EFFECT ($inspect) reaction, and the source is not already a tracked dependency of that reaction. Svelte forbids mutating state from inside pure reactive computations because it creates unpredictable, often cyclical, update order.
Source
Thrown at packages/svelte/src/internal/client/errors.js:492
throw error;
} else {
throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
}
}
/**
* Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state`
* @returns {never}
*/
export function state_unsafe_mutation() {
if (DEV) {
const error = new Error(`state_unsafe_mutation\nUpdating state inside \`$derived(...)\`, \`$inspect(...)\` or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\`\nhttps://svelte.dev/e/state_unsafe_mutation`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
}
}
/**
* A `<svelte:boundary>` `reset` function cannot be called while an error is still being handled
* @returns {never}
*/
export function svelte_boundary_reset_onerror() {
if (DEV) {
const error = new Error(`svelte_boundary_reset_onerror\nA \`<svelte:boundary>\` \`reset\` function cannot be called while an error is still being handled\nhttps://svelte.dev/e/svelte_boundary_reset_onerror`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
}
}View on GitHub (pinned to 20b341f100)
Solutions
- Move the mutation into a $effect (USER_EFFECT) rather than a $derived — effects are allowed to write state.
- If the value is computed, return it from the $derived instead of writing to a separate state.
- Wrap the write in untrack(() => {...}) only if you are certain it is safe and intentional, but prefer restructuring.
Example fix
// before
let a = $state(1);
let b = $state(0);
const sum = $derived(() => { b = a + 1; return b; }); // writes inside derived
// after
let a = $state(1);
const sum = $derived(a + 1); // pure derivation Defensive patterns
Strategy: validation
Validate before calling
// Do not write $state inside $derived, $inspect, or template expressions.
// Move writes into $effect, or return values from $derived.
// If unavoidable, wrap the write in untrack — but prefer restructuring:
// import { untrack } from 'svelte';
// untrack(() => { stateVar = next; }); Prevention
- Keep $derived bodies pure — compute and return, never assign to state.
- Use $effect (not $derived) when you need to write state in response to changes.
- Avoid assignments inside template expressions; compute in the script instead.
- Treat $inspect as read-only observation.
When it happens
Trigger: Assigning to a $state variable inside the body of a $derived, inside a template expression, inside an $inspect callback, or inside a block/branch effect. The guard at sources.js:153-163 checks active_reaction flags and whether the source is in current_sources.
Common situations: Setting state inside $derived to cache a value; mutating inside a template expression like `{state.x = computed}`; writing inside $inspect; effects that should be $effect but were written as $derived; legacy store .set inside derived.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- effect_in_unowned_derived
- effect_orphan
- effect_pending_outside_reaction
- effect_update_depth_exceeded
- flush_sync_in_effect
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/82b50dd1f0229942.
Report an issue: GitHub.