komal.nakrani
Browse Themes
ThemesCategoriesDocsBlogTips & Tricks
Content & MDX••By Komal Nakrani

Fix: Attempted to Render an Undefined Collection Entry

Astro's 'Attempted to render an undefined content collection entry' means getEntry() returned nothing. Check the id, guard before render(), and return a 404.

#Astro#Errors#Content Collections

Astro shows “Attempted to render an undefined content collection entry” when you call render() on something that is undefined, almost always the result of a getEntry() call that didn’t find an entry. The hint is direct: “Check if the entry is undefined before passing it to render().” Fix the id you’re looking up, and guard the call so a missing entry produces a 404 instead of a crash.

Key Takeaways

  • getEntry('blog', id) returns undefined for an unknown id; it doesn’t throw.
  • Ids come from file paths: blog/2026/launch.md is 2026/launch.
  • Guard with if (!entry) before render(entry).
  • In static routes, pass the entry through props so there’s no lookup to get wrong.

Where it usually happens

---
// src/pages/blog/[slug].astro (on-demand)
export const prerender = false;
import { getEntry, render } from 'astro:content';

const entry = await getEntry('blog', Astro.params.slug!);
const { Content } = await render(entry); // entry is undefined for unknown slugs
---

Fix 1: guard and return a 404

---
export const prerender = false;
import { getEntry, render } from 'astro:content';

const entry = await getEntry('blog', Astro.params.slug!);
if (!entry) {
  return new Response(null, { status: 404, statusText: 'Not found' });
}
const { Content } = await render(entry);
---
<h1>{entry.data.title}</h1>
<Content />

An empty 404 response makes Astro render your custom 404 page; the custom 404 page tip shows how to build one.

Fix 2: pass entries as props in static routes

For prerendered pages, look up nothing at render time:

---
import { getCollection, render } from 'astro:content';

export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map((post) => ({ params: { slug: post.id }, props: { post } }));
}

const { post } = Astro.props;
const { Content } = await render(post);
---

Every page receives a real entry, so the error can’t happen.

Fix 3: check the id

Log what exists:

const ids = (await getCollection('blog')).map((p) => p.id);
console.log(ids);

Common mismatches:

  • Subfolders. The id includes the folder: guides/setup, not setup.
  • Extensions. Ids don’t include .md.
  • Custom slugs. If a file sets slug in frontmatter, that value is the id.
  • Old slug habits. Code from older Astro versions may still pass entry.slug, which no longer exists.

References

reference() fields resolve with getEntry(post.data.author). If a referenced entry was deleted, the schema catches it at build time, so this error points at code paths that build ids by hand.

The Astro content collections guide explains ids, getEntry() and render() in full. Related: Duplicate content entry slug. The official entry is in the Astro error reference.

FAQ

Does getEntry() throw if the entry doesn’t exist?

No. It returns undefined, so always check the result.

Why does it work in dev but fail in the build?

Usually an entry filtered out in one place (drafts hidden in production) but still linked or looked up elsewhere.