sveltejs/svelte · error · Error

effect_orphan

effect_orphan

Error message

effect_orphan
`${rune}` can only be used inside an effect (e.g. during component initialisation)
https://svelte.dev/e/effect_orphan

What it means

Thrown by validate_effect() in reactivity/effects.js:55 when $effect/$effect.pre/$inspect is called with both active_effect and active_reaction equal to null — i.e. completely outside any reactive context. Svelte's effect runes require a parent effect (normally the component init effect) so they can be tracked and torn down; with no active reaction at all there is nothing to own them.

Source

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

	} 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`);
	}
}

/**
 * `$effect.pending()` can only be called inside an effect or derived
 * @returns {never}
 */
export function effect_pending_outside_reaction() {
	if (DEV) {
		const error = new Error(`effect_pending_outside_reaction\n\`$effect.pending()\` can only be called inside an effect or derived\nhttps://svelte.dev/e/effect_pending_outside_reaction`);

		error.name = 'Svelte error';

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

View on GitHub (pinned to 20b341f100)

Solutions

  1. Ensure $effect/$inspect is called during component initialisation (top level of a .svelte <script> or a function invoked synchronously from it).
  2. If you need an effect outside a component, use $effect.root(() => { ... }) which creates an explicit root owner.
  3. Move the side effect into an event handler or onMount rather than a bare rune call.

Example fix

// before — module.svelte.js
export function setup() {
  $effect(() => { console.log('runs nowhere'); });
}
setup(); // called from plain JS

// after — call from a component
// Component.svelte
<script>
  import { setup } from './module.svelte.js';
  setup(); // now has an active effect
</script>
Defensive patterns

Strategy: validation

Validate before calling

// Ensure $effect is only called during component init.
// Svelte exposes no public 'is inside effect' check; the discipline is structural:
// only call $effect/$effect.pre/$inspect from the top level of a .svelte <script>
// or from a function synchronously invoked there.

Prevention

When it happens

Trigger: Calling $effect(...), $effect.pre(...), or $inspect(...) at module top-level, inside a plain async function with no component running, in an event handler registered outside component init, or in a setTimeout/setImmediate callback that runs after component init finished. The guard fires at effects.js:52-59 because active_effect===null and active_reaction===null.

Common situations: Calling $effect inside a setTimeout in module scope; invoking a runes-mode .svelte.js helper from plain Node code; refactoring onMount logic into an external function and forgetting it must be called during component init; testing runes code without mounting a component.

Related errors


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