tj/commander.js · error · Error
cannot add command '${newCmd}' as already have command '${ex
Error message
cannot add command '${newCmd}' as already have command '${existingCmd}' What it means
Thrown by Command._registerCommand() at lib/command.js:645-659 when a command (or any of its aliases) collides with an already-registered command's name or aliases. The check uses knownBy() = [name, ...aliases] on both sides, and the message renders the full alias set joined by '|' so you can see exactly what clashed.
Source
Thrown at lib/command.js:656
* Check for command name and alias conflicts with existing commands.
* Register command if no conflicts found, or throw on conflict.
*
* @param {Command} command
* @private
*/
_registerCommand(command) {
const knownBy = (cmd) => {
return [cmd.name()].concat(cmd.aliases());
};
const alreadyUsed = knownBy(command).find((name) =>
this._findCommand(name),
);
if (alreadyUsed) {
const existingCmd = knownBy(this._findCommand(alreadyUsed)).join('|');
const newCmd = knownBy(command).join('|');
throw new Error(
`cannot add command '${newCmd}' as already have command '${existingCmd}'`,
);
}
this._initCommandGroup(command);
this.commands.push(command);
}
/**
* Add an option.
*
* @param {Option} option
* @return {Command} `this` command for chaining
*/
addOption(option) {
this._registerOption(option);
const oname = option.name();View on GitHub (pinned to ba6d13ddb4)
Solutions
- Rename the second command, or remove the duplicate registration.
- Audit aliases — change the alias so it doesn't collide with a sibling command name.
- When auto-discovering subcommands, deduplicate by name/alias before calling addCommand, and log a warning on skip.
Example fix
// before (throws: 'run' collides)
program.command('run').alias('start');
program.command('start');
// after
program.command('run').alias('launch');
program.command('start'); Defensive patterns
Strategy: validation
Validate before calling
function safeAddCommand(parent, cmd) {
const taken = new Set(parent.commands.flatMap(c => [c.name(), ...c.aliases()]));
const novel = [cmd.name(), ...cmd.aliases()].filter(n => taken.has(n));
if (novel.length) throw new Error(`command name/alias conflict: ${novel.join(', ')}`);
return parent.addCommand(cmd);
} Prevention
- Maintain a registry/const of command names and aliases for your app.
- When auto-discovering subcommands, dedupe by name+aliases before registering.
- Audit aliases whenever you rename a command.
When it happens
Trigger: Two `program.command('build')` declarations; adding `cmd1.alias('run')` then `cmd2` named 'run'; addCommand of a subcommand whose alias matches an existing subcommand's name. Each registration re-runs the conflict scan against this.commands.
Common situations: Loading subcommands from a directory where two files resolve to the same name; merging command sets from plugins; an alias that accidentally equals a sibling command's name; refactor that renamed a command but left the old registration in place.
Related errors
- cannot add alias '${alias}' to command '${this.name()}' as a
- Command passed to .addCommand() must have a name - specify t
- Cannot add option '${option.flags}'${this._name && ` to comm
- Command alias can't be the same as its name
- only the last argument can be variadic '${previousArgument.n
AI-assisted analysis of tj/commander.js@ba6d13ddb4 (2026-08-03).
Data as JSON: /data/errors/9a3421478cc32153.json.
Report an issue: GitHub.