sveltejs/svelte · warning · MigrationError

This migration would change the name of a slot (${slot_name}

Error message

This migration would change the name of a slot (${slot_name} to ${name}) making the component unusable

What it means

Thrown when migrating a named `<slot>` to a snippet prop would require renaming the slot (because `state.scope.generate(slot_name)` returns a different identifier than the original slot name, meaning that name is already taken in scope). Renaming would silently break consumers that pass that slot name, so the codemod refuses. Only applies to non-default slots.

Source

Thrown at packages/svelte/src/compiler/migrate/index.js:1315

							.toString();
					}
					slot_props += value === attr.name ? `${value}, ` : `${attr.name}: ${value}, `;
				}
			}
		}

		slot_props += '}';
		if (slot_props === '{ }') {
			slot_props = '';
		}

		const existing_prop = state.props.find((prop) => prop.slot_name === slot_name);
		if (existing_prop) {
			name = existing_prop.local;
		} else if (slot_name !== 'default') {
			name = state.scope.generate(slot_name);
			if (name !== slot_name) {
				throw new MigrationError(
					`This migration would change the name of a slot (${slot_name} to ${name}) making the component unusable`
				);
			}
		}

		if (!existing_prop) {
			state.props.push({
				local: name,
				exported: name,
				init: '',
				bindable: false,
				optional: true,
				slot_name,
				type: `import('svelte').${slot_props ? 'Snippet<[any]>' : 'Snippet'}`
			});
		} else if (existing_prop.needs_refine_type) {
			existing_prop.type = `import('svelte').${slot_props ? 'Snippet<[any]>' : 'Snippet'}`;
			existing_prop.needs_refine_type = false;

View on GitHub (pinned to 20b341f100)

Solutions

  1. Rename the colliding local identifier so the slot name can be preserved, then re-run migrate.
  2. Migrate the file by hand and rename both the slot usage and all consumer call sites consistently.
  3. Rename the slot itself (updating all consumers) before migrating.

Example fix

// before
<script>
  let header = 'x';
</script>
<slot name="header" />

<!-- consumer -->
<Comp>
  <template #header>...</template>
</Comp>

<!-- after (manual: rename the local so the slot keeps its name) -->
<script>
  let headerValue = 'x';
</script>
{@render header()}
Defensive patterns

Strategy: validation

Validate before calling

// Detect named slots whose names collide with in-scope identifiers.
function namedSlotCollisions(source) {
  const slots = [...source.matchAll(/<slot\s+name=["']([\w-]+)["']/g)].map(m => m[1]);
  const idents = [...source.matchAll(/\b(?:let|const|var|function|import)\s+([\w$]+)/g)].map(m => m[1]);
  return slots.filter(s => idents.includes(s));
}
const collisions = namedSlotCollisions(componentSource);
if (collisions.length) { /* rename one side */ }

Try / catch

const { code } = migrate({ filename, source });
if (code.startsWith('<!-- @migration-task') && /migration would change the name of a slot/i.test(code)) {
  // rename the colliding identifier or hand-migrate the slot to a snippet prop
}

Prevention

When it happens

Trigger: Running `migrate()` on a Svelte 4 component that declares a named slot (e.g. `<slot name="header"/>`) whose name collides with an existing in-scope identifier, forcing `scope.generate()` to deduplicate it (e.g. `header` → `header_1`).

Common situations: Components with slots named identically to other locals — e.g. a `header` slot in a component that also imports or declares `header`. More likely after partial migration where snippet props already occupy the name.

Related errors


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