{"record":{"id":"066ef61e5cd6b8a7","repo":"facebook/docusaurus","slug":"options-overwrite-and-migrate-cannot-be-used-t","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/docusaurus/src/commands/writeHeadingIds.ts","lineNumber":75,"sourceCode":" */\nasync function getPathsToWatch(siteDir: string): Promise<string[]> {\n  const context = await loadContext({siteDir});\n  const plugins = await initPlugins(context);\n  return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []);\n}\n\n// TODO Docusaurus v4 - Upgrade commander, use choices() API?\nfunction validateOptions(options: WriteHeadingIDOptions) {\n  const validSyntaxValues: HeadingIdSyntax[] = ['classic', 'mdx-comment'];\n  if (options.syntax && !validSyntaxValues.includes(options.syntax)) {\n    throw new Error(\n      `Invalid --syntax value \"${\n        options.syntax\n      }\". Valid values: ${validSyntaxValues.join(', ')}`,\n    );\n  }\n  if (options.overwrite && options.migrate) {\n    throw new Error(\n      \"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.\",\n    );\n  }\n}\n\nexport async function writeHeadingIds(\n  siteDirParam: string = '.',\n  files: string[] = [],\n  options: WriteHeadingIDOptions = {},\n): Promise<void> {\n  validateOptions(options);\n\n  const siteDir = await fs.realpath(siteDirParam);\n\n  const patterns = files.length ? files : await getPathsToWatch(siteDir);\n\n  const markdownFiles = (\n    await safeGlobby(patterns, {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus/src/commands/writeHeadingIds.ts#L57-L93","documentation":"Thrown by `writeHeadingIds`'s `validateOptions` when both `--overwrite` and `--migrate` are passed. The two flags are mutually exclusive because `--overwrite` already regenerates heading IDs in the target syntax, making `--migrate` a no-op. Passing both indicates the user misunderstood the semantics.","triggerScenarios":"Running `docusaurus write-heading-ids --overwrite --migrate ...` simultaneously.","commonSituations":"User combines flags hoping to do 'both' operations; copy-pasted command from a tutorial that used both; migration script that layers redundant options.","solutions":["Drop `--migrate` and keep `--overwrite` if you want fresh IDs in the target syntax.","Drop `--overwrite` and keep `--migrate` if you only want to convert existing classic IDs to the new syntax.","Re-read the help text to confirm which single flag matches your intent."],"exampleFix":"# before\ndocusaurus write-heading-ids docs --overwrite --migrate\n# after\ndocusaurus write-heading-ids docs --overwrite","handlingStrategy":"validation","validationCode":"if (options.overwrite && options.migrate) {\n  throw new Error('--overwrite and --migrate are mutually exclusive');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use commander's conflicting-flags API to reject this at parse time.","Document each flag's exact semantics prominently.","In scripts, never pass both — pick one based on intent."],"tags":["write-heading-ids","cli","validation"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}