withastro/astro · error · AstroError
ReservedSlotName
ReservedSlotName
Error message
Unable to create a slot named `${slotName}`. `${slotName}` is a reserved slot name. Please update the name of this slot. What it means
At render time Astro wraps a component's slots in a `Slots` instance that exposes each slot name as a boolean property (`slots.has?.('name')` style access). The constructor defines each incoming slot name on the instance, but first rejects any name that already exists as a class member — `has`, `render`, and other prototype methods — because the slot flag would shadow the API. Using one of those names throws `ReservedSlotName`.
Solutions
- Rename the slot to something not used by the Slots class (e.g. `renderSlot`, `hasContent`)
- Update both the child (`slot="newName"`) and the parent's `<slot name="newName" />`
- When wrapping third-party components, check their slot names against the reserved list (`has`, `render`, etc.)
Example fix
<!-- before --> <Layout slot="render">…</Layout> <!-- after --> <Layout slot="main">…</Layout> <!-- and in Layout.astro: <slot name="main" /> -->
Defensive patterns
Strategy: type-guard
Validate before calling
// Component library: validate slot names before passing them through const slotsToPass = Object.fromEntries( Object.entries(userSlots).filter(([name]) => isSafeSlotName(name)), );
Type guard
// Slot names must not collide with Slots class members
const RESERVED_SLOT_NAMES = new Set(['has', 'render', 'renderFederated', 'constructor']);
export function isSafeSlotName(name: string): boolean {
return !RESERVED_SLOT_NAMES.has(name);
} Prevention
- Avoid `render`, `has`, and other API-sounding names when designing slot vocabularies
- Smoke-render wrapper components once after renaming slots
- Document reserved names in your component library's contribution guide
When it happens
Trigger: `<MyComponent slot="render">…</MyComponent>` or `slot="has"`; passing children with those keys programmatically (JSX/MDX named slots); a design system renaming a generic slot to `render` or `has` in a new version, breaking consumers at build/dev render time.
Common situations: Generic wrapper components tempted to call a slot `render`; upgrading a UI library whose slot vocabulary grew into these names; MDX content using `slot` attributes that collide.
Related errors
- Expected second parameter to be an array, received a
- Invalid route — parameter name must match /^[a-zA-Z0-9_$]+$/
- Invalid route — parameter name must match /^[a-zA-Z0-9_$]+$/
- InvalidComponentArgs
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/862b2ede65bc75a2.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/core/render/slots.ts:36
return getFunctionExpression(expression);
}
return expression as (...args: any[]) => any;
}
export class Slots {
#result: SSRResult;
#slots: ComponentSlots | null;
#logger: AstroLogger;
constructor(result: SSRResult, slots: ComponentSlots | null, logger: AstroLogger) {
this.#result = result;
this.#slots = slots;
this.#logger = logger;
if (slots) {
for (const key of Object.keys(slots)) {
if ((this as any)[key] !== undefined) {
throw new AstroError({
...AstroErrorData.ReservedSlotName,
message: AstroErrorData.ReservedSlotName.message(key),
});
}
Object.defineProperty(this, key, {
get() {
return true;
},
enumerable: true,
});
}
}
}
public has(name: string) {
if (!this.#slots) return false;
return Boolean(this.#slots[name]);
}View on GitHub (pinned to 52e6c34790)