{"record":{"id":"9e05fa148128ce87","repo":"withastro/astro","slug":"renderundefinedentryerror","errorCode":"RenderUndefinedEntryError","errorMessage":"Attempted to render an undefined content collection entry.","messagePattern":"Attempted to render an undefined content collection entry\\.","errorType":"error_code","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/content/runtime.ts","lineNumber":572,"sourceCode":"\t\t\t\tctx.update(src);\n\t\t\t}\n\t\t}\n\t});\n\treturn copy;\n}\n\nexport function resolveEntryData<T extends Record<string, unknown>>(\n\tentry: DataEntry<T>,\n\timageAssetMap?: Map<string, ImageMetadata>,\n): T {\n\treturn entry.assetImports?.length\n\t\t? updateImageReferencesInData(entry.data, entry.filePath, imageAssetMap)\n\t\t: structuredClone(entry.data);\n}\n\nexport async function renderEntry(entry: DataEntry) {\n\tif (!entry) {\n\t\tthrow new AstroError(AstroErrorData.RenderUndefinedEntryError);\n\t}\n\trecordContentEntryRender(entry.filePath);\n\n\tif (entry.deferredRender) {\n\t\ttry {\n\t\t\t// @ts-expect-error\tvirtual module\n\t\t\tconst { default: contentModules } = await import('astro:content-module-imports');\n\t\t\tconst renderEntryImport = contentModules.get(entry.filePath);\n\t\t\treturn render({\n\t\t\t\tcollection: '',\n\t\t\t\tid: entry.id,\n\t\t\t\trenderEntryImport,\n\t\t\t});\n\t\t} catch (e) {\n\t\t\tconsole.error(e);\n\t\t}\n\t}\n","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/content/runtime.ts#L554-L590","documentation":"Thrown by renderEntry() when called with a falsy entry. The data layer's render path requires a concrete DataEntry; passing undefined usually means an upstream lookup returned nothing (e.g. getEntry returned undefined) and the caller forwarded it to render without a null check.","triggerScenarios":"Calling renderEntry(undefined) directly; passing the result of getEntry() to render() without checking for undefined: const e = await getEntry(...); const { render } = await renderEntry(e).","commonSituations":"Dynamic routes where the entry doesn't exist; typos in collection/id; race where the entry was deleted between fetch and render; refactors that drop a null check.","solutions":["Null-check the entry before rendering: if (!entry) return Astro.redirect('/404').","Validate that getEntry/getLiveEntry returned a value before calling its render.","In dynamic routes, handle the not-found case explicitly (404) instead of forwarding undefined."],"exampleFix":"// before\nconst entry = await getEntry('posts', params.slug);\nconst { Content } = await renderEntry(entry);\n// after\nconst entry = await getEntry('posts', params.slug);\nif (!entry) return Astro.redirect('/404');\nconst { Content } = await renderEntry(entry);","handlingStrategy":"type-guard","validationCode":"async function renderOr404(entry: Awaited<ReturnType<typeof getEntry>>) {\n  if (!entry) throw new Error('not found');\n  return renderEntry(entry);\n}","typeGuard":"const isDefinedEntry = <T>(e: T | undefined | null): e is T => e != null;","tryCatchPattern":null,"preventionTips":["Always null-check entries from getEntry/getLiveEntry before rendering.","Return a 404 in dynamic routes when entry is missing.","Type the entry as NonNullable before passing to renderEntry."],"tags":["content-collections","rendering","runtime","validation"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}