withastro/astro · critical · Error
Unable to render because it contains an undefined…
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
Thrown from Astro's streaming JSX renderer when a vnode's type is falsy — the component reference being rendered evaluated to undefined. Astro renders JSX from .astro templates and MDX/MD pages by looking up each element's constructor; an undefined one means the name used in markup was never bound to a real component. Typical causes are a typo, a missing import, an import/export shape mismatch, or a circular import that leaves the binding undefined at render time.
Solutions
- Open the page named in the error (result.pathname) and find the JSX element whose component is undefined: verify the import exists and the tag matches it exactly
- Check the import shape: .astro and most framework components are default exports (import Header from './Header.astro'), not named exports
- Verify file-name casing matches the filesystem exactly
- If imports look correct, look for a circular import and move the shared code into a third module
- Run astro check (or tsc) to catch missing or misspelled exports before rendering
Example fix
// before — Header.astro has a default export
import { Header } from './Header.astro';
<html><body><Header /></body></html>
// after
import Header from './Header.astro';
<html><body><Header /></body></html> Defensive patterns
Strategy: type-guard
Validate before calling
---
// dynamic component lookup in frontmatter
import { isRenderableComponent } from '../lib/guards';
const Comp = registry[name];
---
{isRenderableComponent(Comp) ? <Comp {...props} /> : <p>Unknown component: {name}</p>} Type guard
type Renderable = (...args: any[]) => any; const isRenderableComponent = (c: unknown): c is Renderable => typeof c === 'function' || (typeof c === 'object' && c !== null && 'render' in c);
Prevention
- Run astro check (astro check / tsc) in CI to catch missing and misspelled exports before render time
- Use exact file-name casing in imports so code works on case-sensitive Linux CI
- Avoid dynamic component lookups without a fallback branch; guard them with a type guard
- Watch for circular imports when extracting shared helpers out of .astro frontmatter
When it happens
Trigger: Rendering <TypoComp /> where the identifier is misspelled or never imported; import { Header } from './Header.astro' when the module only has a default export (or vice versa); an MDX/.md page using a component passed via the components={{...}} prop with a wrong key; a circular import chain (A imports B imports A) leaving the binding undefined on first render; a component looked up from a map that returned undefined.
Common situations: Renaming an export but not all usages; file-name casing that works on macOS/Windows but breaks on Linux CI (./header.astro vs ./Header.astro); components fetched from data maps that can be absent; refactors that accidentally introduce import cycles between .astro frontmatter and compiled islands.
Related errors
- Unable to render because it contains an undefined…
- Unable to render because it is ! Did you forget to import…
- font family cannot be retrieved by the provider. Did you…
- Error: invalid hydration directive
- ImageNotFound
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/ebd0fae208c2f1b4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/runtime/server/render/streaming.ts:125
};
// Render function for a dynamic node into a (buffered) destination.
const renderDynamic =
(node: unknown) =>
(d: RenderDestination): void | Promise<void> => {
if (isVNode(node)) {
return renderJSX(result, node).then((out) => renderChild(d, out));
}
return renderChild(d, node);
};
// Handle an astro:jsx VNode (JSX in .astro files and MDX/.md pages). Emits
// HTML elements as static, pushes children, and routes components through
// the dynamic path.
const handleVNode = (vnode: AstroVNode) => {
const type = vnode.type as unknown;
if (!type) {
throw new Error(
`Unable to render ${result.pathname} because it contains an undefined Component!\nDid you forget to import the component or is it possible there is a typo?`,
);
}
// Fragment: process its children.
if ((type as any) === Fragment) {
stack.push(vnode.props?.children);
return;
}
// Astro component factory (including `server:defer` islands).
if (isAstroComponentFactory(type)) {
const props: Record<string, unknown> = {};
const slots: Record<string, number | any> = {};
for (const [key, value] of Object.entries(vnode.props ?? {})) {
if (
key === 'children' ||
(value && typeof value === 'object' && (value as any)['$$slot'])View on GitHub (pinned to e294953aa8)