withastro/astro · error · Error
Unable to render ${result.pathname} because it contains an u
Error message
Unable to render ${result.pathname} because it contains an undefined Component!
Did you forget to import the component or is it possible there is a typo? What it means
In the legacy/non-streaming JSX renderer (`renderJSXVNode`), a VNode reached render with a falsy `type`. A VNode's `type` is the component function/class/string-tag; a falsy one means the component reference itself is `undefined`. Astro cannot render an unknown element, so it throws. The message names the current `result.pathname` to help locate the page.
Source
Thrown at packages/astro/src/runtime/server/jsx.ts:68
content += item;
}
}
if (instructions) {
return markHTMLString(new SlotString(content, instructions));
}
return markHTMLString(content);
}
}
return renderJSXVNode(result, vnode);
}
async function renderJSXVNode(result: SSRResult, vnode: AstroVNode): Promise<any> {
if (isVNode(vnode)) {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
switch (true) {
case !vnode.type: {
throw new Error(`Unable to render ${result.pathname} because it contains an undefined Component!
Did you forget to import the component or is it possible there is a typo?`);
}
case (vnode.type as any) === Symbol.for('astro:fragment'):
return renderJSX(result, vnode.props.children);
case isAstroComponentFactory(vnode.type): {
let props: Record<string, any> = {};
let slots: Record<string, any> = {};
for (const [key, value] of Object.entries(vnode.props ?? {})) {
if (key === 'children' || (value && typeof value === 'object' && value['$$slot'])) {
slots[key === 'children' ? 'default' : key] = () => renderJSX(result, value);
} else {
props[key] = value;
}
}
// We don't use renderToString because it doesn't contain the server island script handling
const str = await renderComponentToString(
result,
vnode.type.name,View on GitHub (pinned to d081033d5f)
Solutions
- Import the component with the correct name at the top of the file.
- Verify the identifier matches the export (default vs named) and isn't shadowed/undefined at the call site.
- Guard dynamic component selection with a fallback so the tag is always defined.
Example fix
// before // (Component never imported) <Component /> // Component is undefined // after import Component from '../components/Component.astro'; <Component />
Defensive patterns
Strategy: type-guard
Validate before calling
function assertDefinedComponent(Comp: unknown, name: string): void {
if (!Comp) {
throw new Error(`Component '${name}' is undefined; check the import.`);
}
} Type guard
const isComponent = (v: unknown): v is Function | string => typeof v === 'function' || typeof v === 'string'; // Dynamic JSX guard: const Tag = isComponent(Maybe) ? Maybe : 'div';
Prevention
- Always import components explicitly at the top of the file.
- For dynamic tags, default to a Fragment or placeholder when the lookup misses.
- Enable strict TypeScript so undefined identifiers fail to compile.
When it happens
Trigger: Using an undefined variable as a JSX tag (`<{MaybeMissing} />`); a component variable that resolved to `undefined` due to a failed/conditional import; an object property access that returned undefined then used as a tag; a typo in the component identifier.
Common situations: Forgot to `import` the component; conditional/dynamic component selection where none matched and defaulted to undefined; named import that doesn't exist in the module; refactoring that renamed a component without updating usages.
Related errors
- Unable to render ${result.pathname} because it contains an u
- Unable to render ${displayName} because it is ${Component}!
- Error: invalid hydration directive "${key}". Supported hydra
- MissingMediaQueryDirective
- NoMatchingImport
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/6e15acda473d9731.
Report an issue: GitHub.