withastro/astro · error · AstroError
InvalidFrontmatterInjectionError
InvalidFrontmatterInjectionError
Error message
A remark or rehype plugin attempted to inject invalid frontmatter. Ensure "astro.frontmatter" is set to a valid JSON object that is not `null` or `undefined`.
What it means
Thrown (code `InvalidFrontmatterInjectionError`) after Markdown rendering when a remark or rehype plugin has set `astro.frontmatter` on the file data to something that is not a valid JSON-serializable object — i.e. null or undefined. The plugin validates `renderResult.metadata.frontmatter` with `isFrontmatterValid` before continuing; injected frontmatter must be a plain object.
Source
Thrown at packages/astro/src/vite-plugin-markdown/index.ts:98
if (!renderer) {
const { markdown: md, image } = settings.config;
renderer = md.processor.createRenderer({
image,
syntaxHighlight: md.syntaxHighlight,
shikiConfig: md.shikiConfig,
gfm: md.gfm,
smartypants: md.smartypants,
});
}
const renderResult = await (await renderer).render(raw.content, {
fileURL,
frontmatter: raw.frontmatter,
});
// Improve error message for invalid astro frontmatter
if (!isFrontmatterValid(renderResult.metadata.frontmatter)) {
throw new AstroError(AstroErrorData.InvalidFrontmatterInjectionError);
}
let html = renderResult.code;
const {
headings,
localImagePaths: rawLocalImagePaths,
remoteImagePaths,
frontmatter,
} = renderResult.metadata;
// Add default charset for markdown pages
const isMarkdownPage = isPage(fileURL, settings);
const charset = isMarkdownPage ? '<meta charset="utf-8">' : '';
// Resolve all the extracted images from the content
const localImagePaths: MarkdownImagePath[] = [];
for (const imagePath of rawLocalImagePaths) {
localImagePaths.push({View on GitHub (pinned to d081033d5f)
Solutions
- Ensure your remark/rehype plugin sets frontmatter to a plain object: `file.data.astro.frontmatter = { ...existing, myKey: 'value' }`.
- Never assign null/undefined; if you have nothing to inject, leave the key unset or assign `{}`.
- Spread the existing frontmatter to avoid clobbering other plugins' injections.
Example fix
// before — remark plugin
export function myRemark() {
return (tree, file) => {
file.data.astro.frontmatter = null;
};
}
// after
export function myRemark() {
return (tree, file) => {
file.data.astro.frontmatter = { ...(file.data.astro.frontmatter || {}), myKey: 'value' };
};
} Defensive patterns
Strategy: validation
Validate before calling
function isFrontmatterValid(fm) {
return fm !== null && fm !== undefined && typeof fm === 'object' && !Array.isArray(fm);
} Type guard
function isValidFrontmatter(fm): fm is Record<string, unknown> {
return typeof fm === 'object' && fm !== null && !Array.isArray(fm);
} Prevention
- In remark/rehype plugins, always spread existing frontmatter: { ...file.data.astro.frontmatter, ... }.
- Never assign null/undefined to astro.frontmatter.
- Test your remark plugin against a sample Markdown file before wiring it into the Astro config.
When it happens
Trigger: A custom remark/rehype plugin assigns `file.data.astro.frontmatter = null`, `= undefined`, `= 'string'`, or deletes the key during Markdown processing. Astro's Markdown renderer collects that injected data and the post-render check fails.
Common situations: Writing a remark plugin that conditionally sets frontmatter and forgets to initialize the object. A plugin mutating `file.data.astro.frontmatter` to a non-object. Combining community remark plugins that conflict over frontmatter injection.
Related errors
- [MDX] A remark or rehype plugin attempted to inject invalid
- [MDX] A Sätteri plugin attempted to inject invalid frontmatt
- Failed to parse image reference: ${imagePath}
- InvalidContentEntrySlugError
- `markdown.remarkPlugins`, `markdown.rehypePlugins`, and `mar
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/8d97e45063271435.
Report an issue: GitHub.