withastro/astro · error · Error
Invalid component export path
Error message
Invalid component export path: ${componentExport} What it means
Client-side hydration guard inside the <astro-island> custom element. After the component module loads, the element resolves the component-export attribute (default 'default'). A plain export name that is exactly one of the forbidden keys ('__proto__', 'constructor', 'prototype') is rejected before lookup, because resolving it would touch Object prototype members. This is a prototype-pollution protection for the browser hydration runtime.
Solutions
- Rename the export in the component module and rebuild so the attribute references a valid export name
- Stop hand-writing or mutating <astro-island> markup; let Astro generate it
- Audit any HTML post-processing plugins (minifiers, CDN rewriters) that touch component-export attributes
Example fix
// before (hand-authored island markup) <astro-island component-export="constructor" ...></astro-island> // after <astro-island component-export="MyWidget" ...></astro-island>
Defensive patterns
Strategy: validation
Validate before calling
const FORBIDDEN = new Set(['__proto__', 'constructor', 'prototype']);
const exportName = islandEl.getAttribute('component-export') ?? 'default';
if (FORBIDDEN.has(exportName)) throw new Error('Refusing forbidden export name: ' + exportName); Type guard
function isSafeExportName(name: string): boolean {
return !['__proto__', 'constructor', 'prototype'].includes(name);
} Try / catch
If generating astro-island markup programmatically, wrap attribute assignment in try/catch and log the offending component-export value; hydration errors are already caught internally by handleHydrationError, so surface them via an error boundary or console handler instead of crashing.
Prevention
- Let Astro generate astro-island markup; never hand-author component-export attributes
- Avoid exports literally named constructor or prototype
- Keep HTML minifiers/CDN rewriters away from astro-island attributes
When it happens
Trigger: The component-export attribute of an astro-island element equals '__proto__', 'constructor', or 'prototype'. Reachable via hand-edited or tampered built HTML, a plugin/proxy rewriting island attributes, or a component module that literally exports a member named 'constructor' or 'prototype' and is referenced by that name.
Common situations: Almost never occurs in a normal build; seen when output HTML is mutated by optimizers/minifiers/security appliances, when islands are hand-authored, or when pen-testing tooling injects crafted attribute values.
Related errors
- A resource was added to
- context.csp was used when rendering the route
- Could not render ` `. No matching import has been found for…
- EnvPrefixConflictsWithSecret
- Error: invalid hydration directive
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/543146647a68ee00.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/runtime/server/astro-island.ts:160
if (Astro[directive] === undefined) {
window.addEventListener(`astro:${directive}`, () => this.start(), { once: true });
return;
}
try {
await Astro[directive]!(
async () => {
const rendererUrl = this.getAttribute('renderer-url');
try {
const [componentModule, { default: hydrator }] = await Promise.all([
this.importWithRetry(this.getAttribute('component-url')!),
rendererUrl
? this.importWithRetry(rendererUrl)
: Promise.resolve({ default: () => () => {} }),
]);
const componentExport = this.getAttribute('component-export') || 'default';
if (!componentExport.includes('.')) {
if (FORBIDDEN_COMPONENT_EXPORT_KEYS.has(componentExport)) {
throw new Error(`Invalid component export path: ${componentExport}`);
}
this.Component = componentModule[componentExport];
} else {
this.Component = componentModule;
for (const part of componentExport.split('.')) {
if (
FORBIDDEN_COMPONENT_EXPORT_KEYS.has(part) ||
!this.Component ||
(typeof this.Component !== 'object' && typeof this.Component !== 'function') ||
!Object.hasOwn(this.Component, part)
) {
throw new Error(`Invalid component export path: ${componentExport}`);
}
this.Component = this.Component[part];
}
}
this.hydrator = hydrator;
return this.hydrate;View on GitHub (pinned to 52e6c34790)