withastro/astro · error · AstroError
InvalidContentEntrySlugError
InvalidContentEntrySlugError
Error message
${collection} → ${entryId} has an invalid slug. `slug` must be a string. What it means
Thrown when a content collection entry's reserved `slug` frontmatter field is present but is not a string. Astro runs `z.string().default(generatedSlug).parse(frontmatterSlug)`: an undefined slug falls back to the generated default, but any other non-string type (number, boolean, array, object) fails the Zod parse and is caught and re-thrown as this AstroError. The `slug` field is reserved by Astro for URL generation and is only valid as a string.
Source
Thrown at packages/astro/src/content/utils.ts:145
export type ContentConfig = z.infer<typeof contentConfigParser> & { digest?: 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 d081033d5f)
Solutions
- Open the entry file named in the error message and change the `slug` value to a quoted string (e.g. `slug: "my-post"`).
- If you intended a numeric ID, keep the number in a custom field (e.g. `id: 42`) and set `slug` to a string, or omit `slug` entirely to use the generated slug.
- Run `astro check` or your editor's YAML linter to catch type coercion before build.
- If the slug is generated dynamically, ensure the generator returns a string at runtime.
Example fix
--- # before slug: 42 --- --- # after slug: "post-42" ---
Defensive patterns
Strategy: validation
Validate before calling
// Before writing content, validate slug type in your frontmatter linter
function validateFrontmatterSlug(frontmatter: Record<string, unknown>): string | null {
if ('slug' in frontmatter && frontmatter.slug !== undefined) {
if (typeof frontmatter.slug !== 'string') {
return `slug must be a string, got ${typeof frontmatter.slug}`;
}
}
return null;
} Type guard
function isValidSlug(value: unknown): value is string | undefined {
return value === undefined || typeof value === 'string';
} Try / catch
try {
const entries = await getCollection('blog');
} catch (e) {
if (e instanceof AstroError && e.name === 'InvalidContentEntrySlugError') {
console.error('Fix the slug in the entry file:', e.message);
}
throw e;
} Prevention
- Always quote slug values in YAML frontmatter to prevent type coercion.
- Add a YAML linter or pre-commit hook that checks frontmatter types.
- Document that `slug` is a reserved string-only field for content authors.
When it happens
Trigger: A Markdown/MDX content entry has a frontmatter `slug:` key whose YAML value parses to a non-string type — e.g. `slug: 42` (number), `slug: true` (boolean), `slug: [a, b]` (array), or `slug: {x: 1}` (object). The `parseEntrySlug` function is called from `getEntryData` / `getEntryInfo` during content processing.
Common situations: A developer writes `slug: 123` in frontmatter thinking any unique identifier works. YAML auto-coerces unquoted values (e.g. `slug: 007` becomes the number 7). Migrating from another CMS that used numeric slugs. Accidentally indenting `slug:` under another key so YAML parses it as a nested map.
Related errors
- LiveContentConfigError
- UnsupportedConfigTransformError
- BAD_REQUEST
- LiveContentConfigError
- A content collection is defined with legacy features (e.g. m
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/0097d5e8655cd6b5.
Report an issue: GitHub.