withastro/astro · error · Error
[MDX] A Sätteri plugin attempted to inject invalid frontmatt
Error message
[MDX] A Sätteri plugin attempted to inject invalid frontmatter. Ensure `ctx.data.astro.frontmatter` is a valid object that is not `null` or `undefined`.
What it means
After compiling MDX through the Sätteri pipeline, the integration reads `mdxResult.data.astro.frontmatter` (the final, post-plugin value) and re-validates it. If the resolved frontmatter is missing or not a valid JSON object, it throws a plain `Error` attributing the failure to a Sätteri plugin. This catches plugins that replaced or nulled the frontmatter bag during compilation.
Source
Thrown at packages/integrations/mdx/src/satteri/index.ts:151
? {}
: { smartPunctuation: mdxOptions.smartypants !== false }),
},
fileURL: pathToFileURL(filePath),
jsxImportSource: 'astro',
elementAttributeNameCase: 'html',
data: { astro: astroData },
});
let compiled = mdxResult.code;
// Read the returned bag, not the seeded reference, so a plugin that replaces it is honored.
const astro = mdxResult.data.astro;
const headings = astro?.headings ?? [];
const astroMetadata = mdxResult.data.__astroMetadata ?? createDefaultAstroMetadata();
// Plugins may have mutated frontmatter; emit the final value.
const resolvedFrontmatter = astro?.frontmatter;
if (!resolvedFrontmatter || !isFrontmatterValid(resolvedFrontmatter)) {
throw new Error(
'[MDX] A Sätteri plugin attempted to inject invalid frontmatter. Ensure `ctx.data.astro.frontmatter` is a valid object that is not `null` or `undefined`.',
);
}
compiled = compiled.replace(/^export default MDXContent;\s*$/m, '');
if (imageImportInfo.hasImages) {
// `vite-plugin-mdx-postprocess` wraps Content to map
// `astro-image` → `components.img ?? __AstroImage__`, so a user's
// `export const components = { img: ... }` override is honored.
compiled += `\nimport { Image as ${ASTRO_IMAGE_IMPORT} } from "astro:assets";`;
for (const [src, importName] of imageImportInfo.importedImages) {
compiled += `\nimport ${importName} from ${JSON.stringify(src)};`;
}
compiled += `\nexport const ${USES_ASTRO_IMAGE_FLAG} = true;`;
}
compiled += `\nexport const frontmatter = ${JSON.stringify(resolvedFrontmatter)};`;View on GitHub (pinned to d081033d5f)
Solutions
- Make any plugin that touches frontmatter always leave `ctx.data.astro.frontmatter` as a plain JSON object.
- If you replace `data.astro`, copy `frontmatter` over: `{ ...newAstro, frontmatter: existing.frontmatter ?? {} }`.
- Verify plugin order so a later plugin doesn't null frontmatter after earlier setup.
- Default frontmatter to `{}` rather than allowing it to become undefined.
Example fix
// before
file.data.astro = { ...newData }; // drops frontmatter
// after
file.data.astro = { ...newData, frontmatter: file.data.astro?.frontmatter ?? {} }; Defensive patterns
Strategy: validation
Validate before calling
function isValidFrontmatter(fm: unknown): boolean {
return fm !== null && fm !== undefined && typeof fm === 'object' && !Array.isArray(fm);
} Type guard
function isPlainFrontmatter(v: unknown): v is Record<string, unknown> {
return v !== null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- Preserve `frontmatter` when replacing `data.astro`.
- Default frontmatter to `{}` in any plugin that may clear it.
- Pin plugin order so frontmatter is finalized before re-validation.
When it happens
Trigger: A remark/rehype/Sätteri plugin assigns `ctx.data.astro.frontmatter` to null/undefined or a non-serializable value during compile. A plugin that swaps out the whole `data.astro` object without preserving `frontmatter`. Async frontmatter mutation that resolves after the read.
Common situations: Custom Sätteri/remark plugin overriding frontmatter. Plugin compatibility issue across MDX versions. Frontmatter intentionally cleared in a transform.
Related errors
- [MDX] A remark or rehype plugin attempted to inject invalid
- Expected a matching import for component `${tagName}`. Did y
- InvalidFrontmatterInjectionError
- NoMatchingImport
- The markdown processor "${processor.name}" does not provide
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/f13a8208782538f2.
Report an issue: GitHub.