withastro/astro · error · AstroError

ContentLoaderInvalidDataError

ContentLoaderInvalidDataError

Error message

**${collection}** entry is missing an ID.
Entry missing ID:
${raw}

What it means

After `simpleLoader` validates the schema, it iterates the returned array and explicitly checks each `raw.id`. If an entry has a falsy `id`, it throws `ContentLoaderInvalidDataError` with the offending entry serialized. This is a defensive check beyond schema validation to produce a clear, actionable message.

Source

Thrown at packages/astro/src/content/content-layer.ts:505

		const entry = Array.isArray(unsafeData)
			? unsafeData[firstPathItem as number]
			: unsafeData[firstPathItem as string];

		throw new AstroError({
			...AstroErrorData.ContentLoaderReturnsInvalidId,
			message: AstroErrorData.ContentLoaderReturnsInvalidId.message(context.collection, entry),
		});
	}

	const data = parsedData.data;

	context.store.clear();

	if (Array.isArray(data)) {
		for (const raw of data) {
			if (!raw.id) {
				throw new AstroError({
					...AstroErrorData.ContentLoaderInvalidDataError,
					message: AstroErrorData.ContentLoaderInvalidDataError.message(
						context.collection,
						`Entry missing ID:\n${JSON.stringify({ ...raw, id: undefined }, null, 2)}`,
					),
				});
			}
			const item = await context.parseData({ id: raw.id, data: raw });
			context.store.set({ id: raw.id, data: item });
		}
		return;
	}
	if (typeof data === 'object') {
		for (const [id, raw] of Object.entries(data)) {
			if (raw.id && raw.id !== id) {
				throw new AstroError({
					...AstroErrorData.ContentLoaderInvalidDataError,
					message: AstroErrorData.ContentLoaderInvalidDataError.message(

View on GitHub (pinned to d081033d5f)

Solutions

  1. Filter or repair entries before returning them so every entry has a non-empty string id.
  2. Generate a stable id (e.g. from a slug or hash) when the source lacks one.
  3. Skip entries without an id explicitly if they should not be indexed.

Example fix

// before
const loader = () => fetch('/api/posts').then(r => r.json());
// after
const loader = () => fetch('/api/posts').then(r => r.json()).then(arr => arr.filter(p => p.id).map(p => ({ id: p.id, ...p })));
Defensive patterns

Strategy: validation

Validate before calling

const out = await loader();
if (Array.isArray(out)) {
  for (const raw of out) if (!raw.id) throw new Error('Entry missing id');
}

Type guard

function everyEntryHasId(arr) {
  return arr.every(e => !!e?.id);
}

Prevention

When it happens

Trigger: A function loader returns an array where one or more entries have `id: undefined`, `id: null`, `id: ''`, or no `id` at all.

Common situations: Some CMS items lack a slug; partial DB rows where the id column is null; conditional `id` assignment that drops the field for certain records.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/9efb321d770fba97. Report an issue: GitHub.