sveltejs/svelte · warning · MigrationError
migrating this component would require adding a `$${rune}` r
Error message
migrating this component would require adding a `$${rune}` rune but there's already a variable named ${rune}.
Rename the variable and try again or migrate by hand. What it means
Thrown (as a `MigrationError`) by Svelte's Svelte 4 → 5 codemod when a component needs one of the runes `$derived`, `$props`, or `$bindable` injected, but the component's own scope already declares a user variable with that bare name (e.g. `let derived = ...`). Injecting the rune would shadow or collide with the variable, so the automigrator refuses rather than produce broken code. The migrate entry function catches it and emits the original source back with a `<!-- @migration-task -->` comment instead of crashing.
Source
Thrown at packages/svelte/src/compiler/migrate/index.js:280
str.appendRight(insertion_point, `\n${indent}${legacy_import}`);
}
if (state.script_insertions.size > 0) {
str.appendRight(
insertion_point,
`\n${indent}${[...state.script_insertions].join(`\n${indent}`)}`
);
}
insertion_point = state.props_insertion_point;
/**
* @param {"derived"|"props"|"bindable"} rune
*/
function check_rune_binding(rune) {
const has_rune_binding = !!state.scope.get(rune);
if (has_rune_binding) {
throw new MigrationError(
`migrating this component would require adding a \`$${rune}\` rune but there's already a variable named ${rune}.\n Rename the variable and try again or migrate by hand.`
);
}
}
if (state.props.length > 0 || analysis.uses_rest_props || analysis.uses_props) {
const has_many_props = state.props.length > 3;
const newline_separator = `\n${indent}${indent}`;
const props_separator = has_many_props ? newline_separator : ' ';
let props = '';
if (analysis.uses_props) {
props = `...${state.names.props}`;
} else {
props = state.props
.filter((prop) => !prop.type_only)
.map((prop) => {
let prop_str =
prop.local === prop.exported ? prop.local : `${prop.exported}: ${prop.local}`;View on GitHub (pinned to 20b341f100)
Solutions
- Rename the colliding variable in the source component (e.g. `let props` → `let forwardedProps`) and re-run the migrator.
- If you do not need the automigrator for that file, migrate it by hand and skip the codemod for it.
- Grep the component for `\b(props|derived|bindable)\b` declarations before running migrate to pre-empt the collision.
Example fix
// before
<script>
export let derived;
let derived = computed();
</script>
// after (rename, then migrate)
<script>
let { derivedValue = computed() } = $props();
</script> Defensive patterns
Strategy: validation
Validate before calling
// Before running migrate(), scan the component for rune-name collisions.
function hasRuneNameCollision(source) {
return /\b(let|const|var)\s+(props|derived|bindable)\b/.test(source);
}
if (hasRuneNameCollision(componentSource)) {
// rename before migrating
} Try / catch
// migrate() never throws MigrationError — it returns code with a marker comment.
const { code } = migrate({ filename, source });
if (code.startsWith('<!-- @migration-task')) {
// inspect the embedded message and finish migration by hand
} Prevention
- Avoid naming component variables `props`, `derived`, or `bindable` — reserve them for runes.
- Run a grep for `\b(props|derived|bindable)\b` declarations before invoking the migrator.
- Treat any `<!-- @migration-task -->` comment in migrate output as a required manual step.
When it happens
Trigger: Running `npx sv migrate svelte-5` (or the programmatic `migrate()` export) on a component that (a) needs `$props`/`$derived`/`$bindable` generated and (b) contains a top-level `let derived`, `let props`, or `let bindable` declaration. The `check_rune_binding` helper looks up the rune name in `state.scope` and throws when the binding exists.
Common situations: Pre-existing variables named `props`, `derived`, or `bindable` in Svelte 4 components — `props` in particular is a common local alias for `$props`-style patterns or for forwarded prop bags. Migration succeeds for other components in the batch but stalls on these.
Related errors
- can't migrate `${...}` to `$${rune}` because there's a varia
- can't migrate `: ${...}` to `$${rune}` because there's a var
- This migration would change the name of a slot (${slot_name}
- This migration would change the name of a slot (${name} to $
- Can't migrate code with ${illegal_specifiers.join(' and ')}.
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/ed4fd6b3243376bf.
Report an issue: GitHub.