🔧 Error Fixes
· 2 min read
Last updated on

Astro: Content Collection Schema Validation Error


Content collection error: Invalid frontmatter

What causes this

Your Markdown file’s frontmatter doesn’t match the Zod schema defined in your content config. Astro validates every content file against its schema at build time, and any mismatch causes this error.

Common causes:

  • A required field is missing from the frontmatter
  • A field has the wrong type (string instead of date, string instead of array)
  • A date is formatted incorrectly
  • An enum value doesn’t match the allowed options
  • You added a new required field to the schema but didn’t update existing posts

Fix 1: Check the error message carefully

Astro tells you exactly which file and field failed:

[ERROR] Invalid frontmatter in "src/content/blog/my-post.md"
  title: Required

This means the title field is missing from that file’s frontmatter.

Fix 2: Match your frontmatter to the schema

// src/content.config.ts
const blog = defineCollection({
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

Your frontmatter must match:

---
title: "My Post"
pubDate: 2026-03-15
tags: ["javascript", "tutorial"]
---

Common type mismatches:

  • pubDate: "March 15" — use ISO format: pubDate: 2026-03-15
  • tags: javascript — must be an array: tags: ["javascript"]
  • draft: "true" — must be boolean: draft: true

Fix 3: Make fields optional with defaults

If a field shouldn’t be required:

schema: z.object({
  title: z.string(),
  description: z.string().optional(),
  tags: z.array(z.string()).default([]),
  draft: z.boolean().default(false),
  heroImage: z.string().optional(),
})

.optional() allows the field to be missing. .default() provides a value when missing.

Fix 4: Use z.coerce for flexible types

schema: z.object({
  // Accepts both "2026-03-15" string and actual Date
  pubDate: z.coerce.date(),

  // Accepts both "5" and 5
  order: z.coerce.number(),
})

Fix 5: Validate all files at once

# Build to check all files
npx astro build

# Or check specific files
npx astro check

How to prevent it

  • Add .default() or .optional() to schema fields that aren’t always needed
  • When adding a new required field to the schema, update all existing content files
  • Use z.coerce.date() instead of z.date() for more flexible date parsing
  • Keep your schema as simple as possible — only require fields you actually use in templates
  • Check our Astro cheat sheet for content collection patterns