{"record":{"id":"a4eedda681579c16","repo":"sveltejs/svelte","slug":"can-t-migrate-to-rune-because-the","errorCode":null,"errorMessage":"can't migrate `: ${...}` to `$${rune}` because there's a variable named ${rune}.\n     Rename the variable and try again or migrate by hand.","messagePattern":"can't migrate `: (.+?)` to `\\$(.+?)` because there's a variable named (.+?)\\.\n     Rename the variable and try again or migrate by hand\\.","errorType":"exception","errorClass":"MigrationError","httpStatus":null,"severity":"warning","filePath":"packages/svelte/src/compiler/migrate/index.js","lineNumber":941,"sourceCode":"\t\t\t/** @type {number} */ (node.end),\n\t\t\t'return;'\n\t\t);\n\t},\n\tLabeledStatement(node, { path, state, next }) {\n\t\tif (state.analysis.runes) return;\n\t\tif (path.length > 1) return;\n\t\tif (node.label.name !== '$') return;\n\t\tif (state.derived_labeled_statements.has(node)) return;\n\n\t\tnext();\n\n\t\t/**\n\t\t * @param {\"state\"|\"derived\"} rune\n\t\t */\n\t\tfunction check_rune_binding(rune) {\n\t\t\tconst has_rune_binding = state.scope.get(rune);\n\t\t\tif (has_rune_binding) {\n\t\t\t\tthrow new MigrationError(\n\t\t\t\t\t`can't migrate \\`$: ${state.str.original.substring(/** @type {number} */ (node.body.start), node.body.end)}\\` to \\`$${rune}\\` because there's a variable named ${rune}.\\n     Rename the variable and try again or migrate by hand.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tnode.body.type === 'ExpressionStatement' &&\n\t\t\tnode.body.expression.type === 'AssignmentExpression'\n\t\t) {\n\t\t\tconst { left, right } = node.body.expression;\n\n\t\t\tconst ids = extract_identifiers(left);\n\t\t\tconst [, expression_ids] = extract_all_identifiers_from_expression(right);\n\t\t\tconst bindings = ids.map((id) => /** @type {Binding} */ (state.scope.get(id.name)));\n\n\t\t\tif (bindings.every((b) => b.kind === 'legacy_reactive')) {\n\t\t\t\tif (\n\t\t\t\t\tright.type !== 'Literal' &&","sourceCodeStart":923,"sourceCodeEnd":959,"githubUrl":"https://github.com/sveltejs/svelte/blob/20b341f10048cf1016a2028ac7eee5595cfef6a5/packages/svelte/src/compiler/migrate/index.js#L923-L959","documentation":"Thrown when migrating a reactive `$:` labeled statement to a rune would collide with a variable named `state` or `derived`. The `$:` body source is shown in the message. Same lexical-collision guard as errors 1 and 5, applied specifically to the `$:` → `$derived`/`$state` rewrite path.","triggerScenarios":"Running `migrate()` on a Svelte 4 component that has both a `$:` reactive statement (being rewritten to `$derived` or `$state`) and a top-level binding literally named `state` or `derived`. The `check_rune_binding` helper at line 936 throws.","commonSituations":"Reactive components that also use `state`/`derived` as identifiers (state machines, derived-data caches). The `$:` rewrite is the most common trigger because Svelte 4 components lean heavily on reactive labels.","solutions":["Rename the colliding `state`/`derived` binding in the component, then re-run migrate.","Convert the `$:` statement by hand to `$derived(...)` or `$effect(...)` and skip the codemod for that file.","Grep for `\\b(state|derived)\\b` declarations in components using `$:` before migrating."],"exampleFix":"// before\n<script>\n  let state = 0;\n  $: doubled = state * 2;\n</script>\n\n// after (rename, then migrate)\n<script>\n  let currentState = $state(0);\n  let doubled = $derived(currentState * 2);\n</script>","handlingStrategy":"validation","validationCode":"// Detect `$:` statements in components that also bind `state`/`derived`.\nfunction reactiveLabelWithNameCollision(source) {\n  return /\\$:\\s/.test(source) && /\\b(let|const|var)\\s+(state|derived)\\b/.test(source);\n}\nif (reactiveLabelWithNameCollision(componentSource)) {\n  // rename the binding before migrating\n}","typeGuard":null,"tryCatchPattern":"const { code } = migrate({ filename, source });\nif (code.startsWith('<!-- @migration-task') && /\\$\\$\\{rune\\}` because there's a variable named/i.test(code)) {\n  // hand-convert the `$:` to $derived/$effect after renaming the collision\n}","preventionTips":["Reserve `state` and `derived` as rune identifiers when adopting Svelte 5.","Audit `$:` blocks in components that also use those identifier names before migrating.","Prefer converting reactive labels by hand where the body is complex."],"tags":["svelte5","migration","reactive-statements","naming-collision","codemod"],"backgroundTag":null,"analyzedSha":"20b341f10048cf1016a2028ac7eee5595cfef6a5","analyzedAt":"2026-08-12T23:37:30.399Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}