affaan-m/ECC · error · Error
--launch and --dry-run are mutually exclusive.
Error message
--launch and --dry-run are mutually exclusive.
What it means
parseArgs rejects command lines that pass both --launch and --dry-run. --launch forces a terminal window to open and run the executable, while --dry-run only prints what would happen without spawning anything; together they are contradictory, so the parser fails fast instead of guessing an intent.
Solutions
- Remove either --launch or --dry-run from the command line; keep --dry-run alone to preview the command.
- If a wrapper script injects --launch, drop the manual --dry-run flag or make the wrapper conditional.
- Use --detect (without --launch) if the goal is inspecting terminal capability without launching.
Example fix
// before node open-terminal.js --launch --dry-run -- vim notes.txt // after node open-terminal.js --dry-run -- vim notes.txt
Defensive patterns
Strategy: validation
Validate before calling
const hasLaunch = argv.includes('--launch');
const hasDryRun = argv.includes('--dry-run');
if (hasLaunch && hasDryRun) throw new Error('Pass either --launch or --dry-run, not both.'); Try / catch
try {
const options = parseArgs(argv);
} catch (err) {
if (err.message.includes('mutually exclusive')) {
console.error('Usage: open-terminal [--launch|--dry-run] [--terminal T] [--cwd D] -- <executable>');
process.exitCode = 2;
} else throw err;
} Prevention
- Use a CLI parser with explicit conflict declarations (e.g. commander .conflicts()) so the constraint is enforced at definition time.
- Keep flag sets for 'preview' and 'execute' modes disjoint in wrapper scripts.
- Test wrappers with both flags present to catch accidental merge.
When it happens
Trigger: Invoking `node open-terminal.js --launch --dry-run -- <executable>` (in either order) makes both launchRequested and dryRunRequested true, hitting the mutual-exclusion check after option parsing.
Common situations: Shell aliases or wrapper scripts that hardcode --launch combined with a user-supplied --dry-run; copy-pasting example commands from docs where one already had --launch and the user appends --dry-run to 'see what it would do'; CI templates merging both flags.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- --all-harnesses and --harness are mutually exclusive.
- Choose exactly one memory body source: --stdin or…
- Conflict messages require at least one --file
- connector name required unless --all is set
- graph sync does not accept a session ID when --all is set
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5540097d3a8f63d2.
Report an issue: GitHub.
Appendix: source
Thrown at skills/terminal-opener/scripts/open-terminal.js:137
} else if (argument === '--detect') {
options.detect = true;
} else if (argument === '--launch') {
launchRequested = true;
options.dryRun = false;
} else if (argument === '--dry-run') {
dryRunRequested = true;
options.dryRun = true;
} else if (argument === '--json') {
options.json = true;
} else if (argument === '--help' || argument === '-h') {
options.help = true;
} else {
throw new Error(`Unknown option "${argument}"; put the executable after --.`);
}
}
if (launchRequested && dryRunRequested) {
throw new Error('--launch and --dry-run are mutually exclusive.');
}
validateTerminalName(options.terminal);
validateCwd(options.cwd);
if (!options.help && !options.detect && !options.executable) {
throw new Error('An executable is required after --.');
}
if (options.executable) validateExecutable(options.executable);
validateArgv(options.argv);
return options;
}
function unsupportedPlan(options) {
return {
ok: false,
reason: 'unsupported-terminal',
action: `Terminal "${options.terminal}" is not supported. Install WezTerm, then rerun with --terminal wezterm.`,
terminal: options.terminal,View on GitHub (pinned to 8321021c54)