withastro/astro · error · AstroError
InvalidContentEntrySlugError
InvalidContentEntrySlugError
Error message
${String(collection)} → ${String(entryId)} has an invalid slug. `slug` must be a string. What it means
While syncing markdown/MDX entries, Astro validates the optional frontmatter slug with z.string(), falling back to the filename-generated slug when absent. If a slug field is present but not a string — a number, boolean, list, or unquoted YAML date — parsing fails and the error names the offending collection and entry id.
Solutions
- Open the named entry and make the slug a quoted string: slug: "123".
- Remove the slug field entirely to fall back to the generated filename slug.
- If a script or CMS writes the frontmatter, stringify the slug value before writing.
Example fix
# before --- slug: 2024-05-01 title: My post --- # after --- slug: "2024-05-01" title: My post ---
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build check: frontmatter slug must be a quoted string when present
import { readdir, readFile } from 'node:fs/promises';
import { join } from 'node:path';
for (const file of await readdir('src/content', { recursive: true })) {
if (!String(file).endsWith('.md')) continue;
const lines = (await readFile(join('src/content', file), 'utf8')).split('\n');
const slugLine = lines.find((l) => l.startsWith('slug:'));
if (!slugLine) continue;
const value = slugLine.slice(5).trim();
const quoted = value.startsWith('"') || value.startsWith("'");
if (!quoted) console.error(`slug needs quotes in ${file}: ${value}`);
} Prevention
- Always quote slug values in YAML, especially numeric or date-like ones.
- When generating frontmatter programmatically, coerce slug to String() before writing.
- Add a content lint step to CI that validates frontmatter types.
When it happens
Trigger: Frontmatter such as slug: 123 (number), slug: [a, b] (list), slug: true, or slug: 2024-05-01 which YAML parses as a date; any non-string value the CMS or a script writes into the slug field.
Common situations: Numeric or date-like slugs left unquoted in YAML; CMS exports that emit typed values; frontmatter templates that default slug to null.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to parse image reference
- [ ] Astro now supports MDX! Support for components in ".md"…
- InvalidFrontmatterInjectionError
- ** ** contains invalid content
- A content collection is defined with legacy features (e.g…
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/0097d5e8655cd6b5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/content/utils.ts:149
export type CollectionConfig = ContentConfig['collections'][string];
type EntryInternal = { rawData: string | undefined; filePath: string };
export function parseEntrySlug({
id,
collection,
generatedSlug,
frontmatterSlug,
}: {
id: string;
collection: string;
generatedSlug: string;
frontmatterSlug?: unknown;
}) {
try {
return z.string().default(generatedSlug).parse(frontmatterSlug);
} catch {
throw new AstroError({
...AstroErrorData.InvalidContentEntrySlugError,
message: AstroErrorData.InvalidContentEntrySlugError.message(collection, id),
});
}
}
export async function getEntryData<
TInputData extends Record<string, unknown> = Record<string, unknown>,
TOutputData extends TInputData = TInputData,
>(
entry: {
id: string;
collection: string;
unvalidatedData: TInputData;
_internal: EntryInternal;
},
collectionConfig: CollectionConfig,
shouldEmitFile: boolean,View on GitHub (pinned to e294953aa8)