withastro/astro · warning

[astro] `markdown.remarkPlugins`/`rehypePlugins`/`remarkRehy

Error message

[astro] `markdown.remarkPlugins`/`rehypePlugins`/`remarkRehype` are set, but your `${current.name}` processor doesn't run them. Move them to `unified({...})` from `@astrojs/markdown-remark` and set `markdown.processor: unified({...})` if you want them to apply.

What it means

Same legacy markdown keys, but markdown.processor is set to a non-unified (third-party) processor. Such processors do not run Astro's remark/rehype plugin pipeline, so markdown.remarkPlugins/rehypePlugins/remarkRehype are silently inert; Astro warns once that the options do nothing and how to make them apply.

Source

Thrown at packages/astro/src/core/config/validate.ts:115

			target.options.rehypePlugins.push(...rehypePlugins.slice(counts.rehype));
		}
		// `remarkRehype` is an object, so Object.assign is idempotent for unchanged keys
		// and absorbs any new keys integrations add.
		Object.assign(target.options.remarkRehype, remarkRehype);
		migratedLegacyPluginCounts.set(target.options, {
			remark: remarkPlugins.length,
			rehype: rehypePlugins.length,
		});
		if (!didWarnAboutLegacyMarkdownPlugins) {
			didWarnAboutLegacyMarkdownPlugins = true;
			console.warn(
				'[astro] `markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` are deprecated. Pass them to `unified({...})` from `@astrojs/markdown-remark` directly instead.',
			);
		}
	} else if (!didWarnAboutProcessorMismatch) {
		// Third-party processors can't run remark/rehype plugins. And if they can, they should be passed directly to the processor (like it is for unified) instead of the legacy keys, so we warn either way.
		didWarnAboutProcessorMismatch = true;
		console.warn(
			`[astro] \`markdown.remarkPlugins\`/\`rehypePlugins\`/\`remarkRehype\` are set, but your ` +
				`\`${current.name}\` processor doesn't run them. Move them to \`unified({...})\` from ` +
				'`@astrojs/markdown-remark` and set `markdown.processor: unified({...})` if you want ' +
				'them to apply.',
		);
	}
}

/**
 * Used twice:
 * - To validate the user config
 * - To validate the config after all integrations (that may have updated it)
 */
export async function validateConfigRefined(updatedConfig: AstroConfig): Promise<AstroConfig> {
	await coerceLegacyMarkdownPlugins(updatedConfig);
	warnDeprecatedMarkdownOptions(updatedConfig);
	return await AstroConfigRefinedSchema.parseAsync(updatedConfig, { error: errorMap });
}

View on GitHub (pinned to 52e6c34790)

Solutions

  1. If the plugins must apply, switch to unified: markdown: { processor: unified({ ...plugins }) }
  2. If the new processor is intended, delete the legacy plugin keys and configure plugins on that processor natively
  3. Verify rendered output after migration — the plugins were silently skipped before

Example fix

// before — third-party processor ignores the legacy keys
export default defineConfig({
  markdown: {
    processor: satteri(),
    remarkPlugins: [remarkToc], // never runs
  },
});

// after — use a processor that runs the plugins
import { unified } from '@astrojs/markdown-remark';
export default defineConfig({
  markdown: { processor: unified({ remarkPlugins: [remarkToc] }) },
});
Defensive patterns

Strategy: validation

Validate before calling

// invariant: legacy plugin keys only allowed with the unified processor
const usesUnified = config.markdown?.processor === undefined || isUnified(config.markdown?.processor);
const hasLegacy = ['remarkPlugins', 'rehypePlugins', 'remarkRehype'].some(
  (k) => config.markdown?.[k] !== undefined,
);
if (hasLegacy && !usesUnified) {
  throw new Error('markdown plugins set but processor does not run them');
}

Prevention

When it happens

Trigger: markdown.processor set to a custom/third-party processor (e.g. satteri) AND markdown.remarkPlugins / rehypePlugins / remarkRehype set — the fold only applies to the unified processor, so the else-branch fires.

Common situations: Switching to an experimental markdown processor while keeping old plugin config; sharing markdown config snippets between projects that use different processors.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/01cd7dd0414d8536. Report an issue: GitHub.