sveltejs/svelte · error · Error

rune_outside_svelte

rune_outside_svelte

Error message

rune_outside_svelte
The `${rune}` rune is only available inside `.svelte` and `.svelte.js/ts` files
https://svelte.dev/e/rune_outside_svelte

What it means

Thrown at index-client.js:29 via a global getter trap installed by throw_rune_error(). Outside a .svelte, .svelte.js, or .svelte.ts file the compiler never rewrites rune calls ($state, $effect, $derived, $inspect, $props, $bindable) into runtime APIs; instead a global getter is installed that throws this error so misuse fails loudly rather than silently being treated as a plain identifier.

Source

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

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

/**
 * The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
 * @param {string} rune
 * @returns {never}
 */
export function rune_outside_svelte(rune) {
	if (DEV) {
		const error = new Error(`rune_outside_svelte\nThe \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files\nhttps://svelte.dev/e/rune_outside_svelte`);

		error.name = 'Svelte error';

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

/**
 * `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
 * @returns {never}
 */
export function set_context_after_init() {
	if (DEV) {
		const error = new Error(`set_context_after_init\n\`setContext\` must be called when a component first initializes, not in a subsequent effect or after an \`await\` expression\nhttps://svelte.dev/e/set_context_after_init`);

		error.name = 'Svelte error';

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

View on GitHub (pinned to 20b341f100)

Solutions

  1. Rename the file to .svelte.js or .svelte.ts so the compiler processes the runes.
  2. If the file must stay plain .js, do not use runes — pass reactive values in/out via function parameters and return values.
  3. Move the runes-using code into a .svelte component or .svelte.js module.

Example fix

// before — utils.js (plain)
export const count = $state(0); // throws

// after — rename to utils.svelte.js
export const count = $state(0); // compiler rewrites to runtime API
Defensive patterns

Strategy: validation

Validate before calling

// Use runes only in .svelte, .svelte.js, or .svelte.ts files.
// Check file extension before writing runes:
import path from 'node:path';
function canUseRunes(file) {
  return /\.svelte(\.js|\.ts)?$/.test(path.extname(file));
}

Prevention

When it happens

Trigger: Writing `$state(0)` or any other rune in a plain .js / .ts / .mjs file. Because the compiler only processes .svelte* files, the rune is left as-is, resolves to the trapped global, and throws on access.

Common situations: Extracting reactive logic into a utility and forgetting to rename the file to .svelte.js; copy-pasting runes code into a plain module; importing a runes-using helper from a non-svelte file that was renamed.

Related errors


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