{"record":{"id":"da900525a83adbb5","repo":"sveltejs/svelte","slug":"can-t-migrate-code-with-illegal-specifiers-join","errorCode":null,"errorMessage":"Can't migrate code with ${illegal_specifiers.join(' and ')}. Please migrate by hand.","messagePattern":"Can't migrate code with (.+?)\\. Please migrate by hand\\.","errorType":"exception","errorClass":"MigrationError","httpStatus":null,"severity":"warning","filePath":"packages/svelte/src/compiler/migrate/index.js","lineNumber":538,"sourceCode":"\t\t\t\t\t\t\tstate.str.original.indexOf(',', specifier.end) !== -1 &&\n\t\t\t\t\t\t\tstate.str.original.indexOf(',', specifier.end) <\n\t\t\t\t\t\t\t\tstate.str.original.indexOf('}', specifier.end)\n\t\t\t\t\t\t\t\t? state.str.original.indexOf(',', specifier.end) + 1\n\t\t\t\t\t\t\t\t: specifier.end\n\t\t\t\t\t\t);\n\t\t\t\t\t\twhile (state.str.original[end].trim() === '') end++;\n\t\t\t\t\t\tstate.str.remove(/** @type {number} */ (specifier.start), end);\n\t\t\t\t\t\tremoved_specifiers++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tillegal_specifiers.push(specifier.imported.name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (removed_specifiers === node.specifiers.length) {\n\t\t\t\tstate.str.remove(/** @type {number} */ (node.start), /** @type {number} */ (node.end));\n\t\t\t}\n\t\t\tif (illegal_specifiers.length > 0) {\n\t\t\t\tthrow new MigrationError(\n\t\t\t\t\t`Can't migrate code with ${illegal_specifiers.join(' and ')}. Please migrate by hand.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\tExportNamedDeclaration(node, { state, next }) {\n\t\tif (node.declaration) {\n\t\t\tnext();\n\t\t\treturn;\n\t\t}\n\n\t\tlet count_removed = 0;\n\t\tfor (const specifier of node.specifiers) {\n\t\t\tif (specifier.local.type !== 'Identifier') continue;\n\n\t\t\tconst binding = state.scope.get(specifier.local.name);\n\t\t\tif (binding?.kind === 'bindable_prop') {\n\t\t\t\tstate.str.remove(","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/sveltejs/svelte/blob/20b341f10048cf1016a2028ac7eee5595cfef6a5/packages/svelte/src/compiler/migrate/index.js#L520-L556","documentation":"Thrown by the migrate codemod when a `<script>` import statement contains specifiers the automigrator cannot safely rewrite or drop (tracked in `illegal_specifiers`). The remaining specifiers are joined into the message. It is caught by the migrate entry point and surfaced as a `<!-- @migration-task -->` comment in the returned source.","triggerScenarios":"Running `migrate()` on a component whose `<script context=\"module\">` or instance script imports symbols that the Svelte 4→5 transform treats as illegal (typically lifecycle/hook re-exports or specifiers tied to APIs removed in runes mode). The visitor collects offending `specifier.imported.name` entries and throws once the import node is processed.","commonSituations":"Components that re-export Svelte 4 lifecycle functions (`onMount`, `afterUpdate`, etc.) from `svelte` in a module script, or that import helpers used only by legacy patterns the codemod rewrites away. Most often seen in shared utility/component libraries.","solutions":["Read the named specifiers in the error and manually rewrite that import in the component, then re-run migrate.","Move the offending import into a plain `.js`/`.ts` module instead of a `<script context=\"module\">` block.","Migrate the affected file by hand and exclude it from the batch run."],"exampleFix":"// before\n<script context=\"module\">\n  import { onMount, afterUpdate } from 'svelte';\n</script>\n\n// after (keep only what still applies; afterUpdate has no runes equivalent)\n<script>\n  import { onMount } from 'svelte';\n</script>","handlingStrategy":"validation","validationCode":"// Before migrating, scan module scripts for imports the codemod rejects.\nfunction riskyModuleImports(source) {\n  const matches = source.match(/<script\\s+context=[\"']module[\"'][\\s\\S]*?<\\/script>/g) || [];\n  // flag re-exports of svelte lifecycle hooks or legacy helpers\n  return matches.some(s => /import\\s*\\{[^}]*(onMount|afterUpdate|beforeUpdate|onDestroy)/.test(s));\n}","typeGuard":null,"tryCatchPattern":"const { code } = migrate({ filename, source });\nif (/illegal|cannot be automatically migrated/i.test(code) && code.startsWith('<!-- @migration-task')) {\n  // open the file and rewrite the flagged import by hand\n}","preventionTips":["Keep `svelte` imports in regular instance scripts, not `<script context=\"module\">` blocks.","Avoid re-exporting Svelte lifecycle functions from component module scripts.","Inspect migrate output for `@migration-task` comments after each batch run."],"tags":["svelte5","migration","imports","codemod","module-script"],"backgroundTag":null,"analyzedSha":"20b341f10048cf1016a2028ac7eee5595cfef6a5","analyzedAt":"2026-08-12T23:37:30.399Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}