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
- Rename the file to .svelte.js or .svelte.ts so the compiler processes the runes.
- If the file must stay plain .js, do not use runes — pass reactive values in/out via function parameters and return values.
- 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
- Name any module that uses runes with a .svelte.js or .svelte.ts extension.
- Keep non-reactive utilities in plain .js/.ts and pass reactive values via parameters.
- Configure your bundler/editor to treat .svelte.js files as compiled.
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
- 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/21c9c94fc52f1cbf.
Report an issue: GitHub.