{"record":{"id":"7a70189e7e46035a","repo":"yamadashy/repomix","slug":"options-optiona-name-cannot-be-used-with-opt","errorCode":null,"errorMessage":"${options[optionA].name} cannot be used with ${options[optionB].name}. ${message}","messagePattern":"(.+?) cannot be used with (.+?)\\. (.+?)","errorType":"exception","errorClass":"RepomixError","httpStatus":null,"severity":"error","filePath":"src/cli/actions/defaultAction.ts","lineNumber":471,"sourceCode":"    },\n    copy: {\n      enabled: config.output.copyToClipboard,\n      name: '--copy',\n    },\n  };\n\n  // Define conflicts: [optionA, optionB, errorMessage]\n  const conflicts: [keyof typeof options, keyof typeof options, string][] = [\n    ['splitOutput', 'stdout', 'Split output requires writing to filesystem.'],\n    ['splitOutput', 'skillGenerate', 'Skill output is a directory.'],\n    ['splitOutput', 'copy', 'Split output generates multiple files.'],\n    ['skillGenerate', 'stdout', 'Skill output requires writing to filesystem.'],\n    ['skillGenerate', 'copy', 'Skill output is a directory and cannot be copied to clipboard.'],\n  ];\n\n  for (const [optionA, optionB, message] of conflicts) {\n    if (options[optionA].enabled && options[optionB].enabled) {\n      throw new RepomixError(`${options[optionA].name} cannot be used with ${options[optionB].name}. ${message}`);\n    }\n  }\n};\n","sourceCodeStart":453,"sourceCodeEnd":475,"githubUrl":"https://github.com/yamadashy/repomix/blob/f465ad909315a22120636baf03fa5e28701a50cb/src/cli/actions/defaultAction.ts#L453-L475","documentation":"validateConflictingOptions checks a table of mutually exclusive option pairs and throws this templated error when both flags in a pair are enabled, e.g. --skill-generate with --stdout (skill output must be written to the filesystem) or --skill-generate with --copy (a skill directory cannot go to the clipboard). It runs at the start of runDefaultAction so conflicts fail before any packing (src/cli/actions/defaultAction.ts:471).","triggerScenarios":"`repomix --skill-generate --stdout`; `repomix --skill-generate --copy`; any other pair in the conflicts table where options[optionA].enabled && options[optionB].enabled, including conflicts enabled indirectly via config or multiple flags (e.g. --stdout implied by other settings).","commonSituations":"Long command lines assembled from different examples where two output targets accumulate; CI configs merging shared flag fragments; users assuming skill output can also be piped or copied like normal pack output.","solutions":["Pick one output mode: keep --skill-generate and remove --stdout/--copy.","If you need stdout or clipboard output, remove --skill-generate and pack normally.","Inspect the resolved flags (echo the command, or run with minimal flags) to find which two conflicting flags are both being set, including flags inherited from wrapper scripts."],"exampleFix":"# before\nrepomix --skill-generate --skill-output ./skill --stdout\n# after\nrepomix --skill-generate --skill-output ./skill","handlingStrategy":"validation","validationCode":"const conflicts = [['--skill-generate', '--stdout'], ['--skill-generate', '--copy']];\nfor (const [a, b] of conflicts) {\n  if (args.includes(a) && args.includes(b)) throw new Error(`${a} and ${b} are mutually exclusive`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await repomixRun(args);\n} catch (e) {\n  const m = String(e.message).match(/^(.+) cannot be used with (.+)\\./);\n  if (m) throw new Error(`Remove either ${m[1]} or ${m[2]} from the command`);\n  throw e;\n}","preventionTips":["Decide on one output mode (skill dir, stdout, clipboard, file) per invocation.","Avoid merging flag fragments from multiple example commands.","When wrapping repomix in scripts, let callers pick an output mode and assert only one is set."],"tags":["cli","argument-validation","flag-conflict","repomix"],"backgroundTag":"mutually-exclusive-cli-options","analyzedSha":"f465ad909315a22120636baf03fa5e28701a50cb","analyzedAt":"2026-08-29T01:27:42.024Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}