facebook/docusaurus · error · Error

Invalid --syntax value "${options.syntax}". Valid values: ${

Error message

Invalid --syntax value "${options.syntax}". Valid values: ${validSyntaxValues.join(', ')}

What it means

Thrown by `writeHeadingIds`'s `validateOptions` when the `--syntax` flag is set to anything other than `'classic'` or `'mdx-comment'`. These are the only two heading-ID syntaxes Docusaurus knows how to emit. The TODO comment notes this manual validation should be replaced with commander's `choices()` API in v4.

Source

Thrown at packages/docusaurus/src/commands/writeHeadingIds.ts:68

}

/**
 * We only handle the "paths to watch" because these are the paths where the
 * markdown files are. Also we don't want to transform the site md docs that do
 * not belong to a content plugin. For example ./README.md should not be
 * transformed
 */
async function getPathsToWatch(siteDir: string): Promise<string[]> {
  const context = await loadContext({siteDir});
  const plugins = await initPlugins(context);
  return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []);
}

// TODO Docusaurus v4 - Upgrade commander, use choices() API?
function validateOptions(options: WriteHeadingIDOptions) {
  const validSyntaxValues: HeadingIdSyntax[] = ['classic', 'mdx-comment'];
  if (options.syntax && !validSyntaxValues.includes(options.syntax)) {
    throw new Error(
      `Invalid --syntax value "${
        options.syntax
      }". Valid values: ${validSyntaxValues.join(', ')}`,
    );
  }
  if (options.overwrite && options.migrate) {
    throw new Error(
      "Options --overwrite and --migrate cannot be used together.\nThe --overwrite already re-generates IDs in the target syntax, so the --migrate option wouldn't have any effect.",
    );
  }
}

export async function writeHeadingIds(
  siteDirParam: string = '.',
  files: string[] = [],
  options: WriteHeadingIDOptions = {},
): Promise<void> {
  validateOptions(options);

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Use one of the two supported values: `--syntax=classic` or `--syntax=mdx-comment`.
  2. Omit `--syntax` entirely to use the default syntax.
  3. Check the installed Docusaurus version's `--help` output for the current valid syntax list.

Example fix

# before
docusaurus write-heading-ids docs --syntax=clasisc  # typo
# after
docusaurus write-heading-ids docs --syntax=classic
Defensive patterns

Strategy: validation

Validate before calling

const valid: HeadingIdSyntax[] = ['classic', 'mdx-comment'];
if (options.syntax && !valid.includes(options.syntax)) {
  throw new Error(`--syntax must be one of: ${valid.join(', ')}`);
}

Type guard

function isValidSyntax(v: unknown): v is 'classic' | 'mdx-comment' {
  return v === 'classic' || v === 'mdx-comment';
}

Prevention

When it happens

Trigger: Running `docusaurus write-heading-ids --syntax=<value>` with `<value>` not in `['classic', 'mdx-comment']` (e.g. a typo, a made-up value, or a future syntax not yet supported).

Common situations: Typo like `--syntax=clasisc`; passing an unsupported value seen in an unrelated tool; copy-pasting a flag from an old/newer Docusaurus version with a different syntax set.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/02152cac8fc65466. Report an issue: GitHub.