{"record":{"id":"0097d5e8655cd6b5","repo":"withastro/astro","slug":"invalidcontententryslugerror","errorCode":"InvalidContentEntrySlugError","errorMessage":"${collection} → ${entryId} has an invalid slug. `slug` must be a string.","messagePattern":"(.+?) → (.+?) has an invalid slug\\. `slug` must be a string\\.","errorType":"error_code","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/content/utils.ts","lineNumber":145,"sourceCode":"export type ContentConfig = z.infer<typeof contentConfigParser> & { digest?: string };\n\ntype EntryInternal = { rawData: string | undefined; filePath: string };\n\nexport function parseEntrySlug({\n\tid,\n\tcollection,\n\tgeneratedSlug,\n\tfrontmatterSlug,\n}: {\n\tid: string;\n\tcollection: string;\n\tgeneratedSlug: string;\n\tfrontmatterSlug?: unknown;\n}) {\n\ttry {\n\t\treturn z.string().default(generatedSlug).parse(frontmatterSlug);\n\t} catch {\n\t\tthrow new AstroError({\n\t\t\t...AstroErrorData.InvalidContentEntrySlugError,\n\t\t\tmessage: AstroErrorData.InvalidContentEntrySlugError.message(collection, id),\n\t\t});\n\t}\n}\n\nexport async function getEntryData<\n\tTInputData extends Record<string, unknown> = Record<string, unknown>,\n\tTOutputData extends TInputData = TInputData,\n>(\n\tentry: {\n\t\tid: string;\n\t\tcollection: string;\n\t\tunvalidatedData: TInputData;\n\t\t_internal: EntryInternal;\n\t},\n\tcollectionConfig: CollectionConfig,\n\tshouldEmitFile: boolean,","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/content/utils.ts#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"---\n# before\nslug: 42\n---\n\n---\n# after\nslug: \"post-42\"\n---","handlingStrategy":"validation","validationCode":"// Before writing content, validate slug type in your frontmatter linter\nfunction validateFrontmatterSlug(frontmatter: Record<string, unknown>): string | null {\n  if ('slug' in frontmatter && frontmatter.slug !== undefined) {\n    if (typeof frontmatter.slug !== 'string') {\n      return `slug must be a string, got ${typeof frontmatter.slug}`;\n    }\n  }\n  return null;\n}","typeGuard":"function isValidSlug(value: unknown): value is string | undefined {\n  return value === undefined || typeof value === 'string';\n}","tryCatchPattern":"try {\n  const entries = await getCollection('blog');\n} catch (e) {\n  if (e instanceof AstroError && e.name === 'InvalidContentEntrySlugError') {\n    console.error('Fix the slug in the entry file:', e.message);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["content-collections","frontmatter","zod","slug"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}