sveltejs/svelte · error · Error

effect_in_unowned_derived

effect_in_unowned_derived

Error message

effect_in_unowned_derived
Effect cannot be created inside a `$derived` value that was not itself created inside an effect
https://svelte.dev/e/effect_in_unowned_derived

What it means

Thrown by validate_effect() in reactivity/effects.js:58 when $effect/$effect.pre/$inspect is invoked while active_effect is null but active_reaction is non-null. This means the call is happening inside a $derived whose chain does not trace back to an owning effect (an 'unowned' derived, e.g. a top-level module-scope $derived). Svelte forbids this because effects created without an owner can never be cleaned up and would leak or run detached from any component lifecycle.

Source

Thrown at packages/svelte/src/internal/client/errors.js:198

		throw error;
	} else {
		throw new Error(`https://svelte.dev/e/effect_in_teardown`);
	}
}

/**
 * Effect cannot be created inside a `$derived` value that was not itself created inside an effect
 * @returns {never}
 */
export function effect_in_unowned_derived() {
	if (DEV) {
		const error = new Error(`effect_in_unowned_derived\nEffect cannot be created inside a \`$derived\` value that was not itself created inside an effect\nhttps://svelte.dev/e/effect_in_unowned_derived`);

		error.name = 'Svelte error';

		throw error;
	} else {
		throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`);
	}
}

/**
 * `%rune%` can only be used inside an effect (e.g. during component initialisation)
 * @param {string} rune
 * @returns {never}
 */
export function effect_orphan(rune) {
	if (DEV) {
		const error = new Error(`effect_orphan\n\`${rune}\` can only be used inside an effect (e.g. during component initialisation)\nhttps://svelte.dev/e/effect_orphan`);

		error.name = 'Svelte error';

		throw error;
	} else {
		throw new Error(`https://svelte.dev/e/effect_orphan`);
	}

View on GitHub (pinned to 20b341f100)

Solutions

  1. Move the $effect out of the $derived and into a component body or $effect.root so it has a real owner.
  2. Replace the effect-inside-derived with pure derivation — compute the value, perform side effects in a separate $effect that reads the derived.
  3. If you truly need an effect with no component owner, wrap it in $effect.root(...) and manage teardown explicitly.

Example fix

// before
export const data = $derived.by(() => {
  $effect(() => { console.log('side effect') });
  return fetchValue();
});

// after — keep the derived pure, run the effect in a component
export const data = $derived.by(() => fetchValue());
// in a .svelte component:
$effect(() => { console.log('side effect', data); });
Defensive patterns

Strategy: validation

Validate before calling

// Before calling $effect inside a derived, ensure the derived is owned by an effect.
// In Svelte there is no public API to check ownership at runtime; instead validate structurally:
// Never place $effect inside $derived.by/$derived unless the derived is created within a component.
// Refactor: keep deriveds pure.
function safeEffectInDerived(getter) {
  // $effect must be called from a component or $effect.root, not from a derived.
  throw new Error('Move the $effect out of the $derived; deriveds must be pure.');
}

Prevention

When it happens

Trigger: Calling $effect(() => {...}) inside the body of a $derived(...) that was itself created outside any component/effect (module scope, or a plain .svelte.js function not called from a component). The validate_effect() guard at effects.js:52-59 fires because active_effect===null (no owner) yet active_reaction!==null (we are inside the derived's evaluation).

Common situations: Creating a top-level `const x = $derived(() => { $effect(() => {...}) })` in a .svelte.js module; refactoring logic out of a component into a derived helper that internally tries to register a side effect; mixing $effect into derived-by-callable patterns during Svelte 5 runes migration.

Related errors


AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12). Data as JSON: /api/errors/1ef9aab99ad01fbc. Report an issue: GitHub.