sveltejs/svelte · error · Error

async_derived_orphan

async_derived_orphan

Error message

async_derived_orphan
Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
https://svelte.dev/e/async_derived_orphan

What it means

Runtime error `async_derived_orphan`: a `$derived(...)` expression contains an `await`, but the derived was not created inside an effect (`$effect`) tree. Svelte disallows orphan async deriveds because there is no owner effect to manage the async lifecycle. In production only the URL is thrown; in DEV the full message is shown.

Source

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

/* This file is generated by scripts/process-messages/index.js. Do not edit! */

import { DEV } from 'esm-env';

export *  from '../shared/errors.js';

/**
 * Cannot create a `$derived(...)` with an `await` expression outside of an effect tree
 * @returns {never}
 */
export function async_derived_orphan() {
	if (DEV) {
		const error = new Error(`async_derived_orphan\nCannot create a \`$derived(...)\` with an \`await\` expression outside of an effect tree\nhttps://svelte.dev/e/async_derived_orphan`);

		error.name = 'Svelte error';

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

/**
 * Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead
 * @returns {never}
 */
export function bind_invalid_checkbox_value() {
	if (DEV) {
		const error = new Error(`bind_invalid_checkbox_value\nUsing \`bind:value\` together with a checkbox input is not allowed. Use \`bind:checked\` instead\nhttps://svelte.dev/e/bind_invalid_checkbox_value`);

		error.name = 'Svelte error';

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

View on GitHub (pinned to 20b341f100)

Solutions

  1. Move the async work into an `$effect` (or `$effect.pre`) and store the result in a `$state` variable that the derived reads.
  2. Ensure the `$derived` is created inside an `$effect.root` if you genuinely need a detached async derived.
  3. Refactor to a derived that reads an already-resolved value (e.g. combine with `{#await}` in the template).

Example fix

// before
let data = $derived(await fetch('/api').then(r => r.json()));

// after
let data = $state();
$effect(() => {
  fetch('/api').then(r => r.json()).then(v => data = v);
});
Defensive patterns

Strategy: validation

Validate before calling

// Structural check: ensure no $derived body contains a top-level await at component scope.
// (Best done as an ESLint rule or a pre-commit grep on the source.)
function riskyAsyncDerived(source) {
  return /\$derived\s*\(\s*(?:async\s|\(?\s*await)/.test(source);
}

Prevention

When it happens

Trigger: At runtime, evaluating `$derived(await fetch(...))` (or any `$derived` whose expression contains `await`) at the top level of a component or in a context that is not inside an `$effect`/`$effect.root`. The derived has no parent effect to own the async work.

Common situations: Migrating reactive statements that performed async work into `$derived` instead of `$effect`; using `$derived` to compute a value from a promise at component init; calling async helpers inside a derived in a snippet or store factory.

Related errors


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