tj/commander.js · error · Error
cannot add alias '${alias}' to command '${this.name()}' as a
Error message
cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}' What it means
Thrown by Command.alias() at lib/command.js:2279-2288 when adding an alias that already matches a sibling command's name or alias (scoped to this.parent's commands via _findCommand). Mirrors _registerCommand's conflict logic (error[8]) but for aliases added after the fact. The message renders the existing command's full name+aliases joined by '|' for diagnosis.
Source
Thrown at lib/command.js:2285
// eslint-disable-next-line @typescript-eslint/no-this-alias
let command = this;
if (
this.commands.length !== 0 &&
this.commands[this.commands.length - 1]._executableHandler
) {
// assume adding alias for last added executable subcommand, rather than this
command = this.commands[this.commands.length - 1];
}
if (alias === command._name)
throw new Error("Command alias can't be the same as its name");
const matchingCommand = this.parent?._findCommand(alias);
if (matchingCommand) {
// c.f. _registerCommand
const existingCmd = [matchingCommand.name()]
.concat(matchingCommand.aliases())
.join('|');
throw new Error(
`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`,
);
}
command._aliases.push(alias);
return this;
}
/**
* Set aliases for the command.
*
* Only the first alias is shown in the auto-generated help.
*
* @param {string[]} [aliases]
* @return {(string[]|Command)}
*/
aliases(aliases) {View on GitHub (pinned to ba6d13ddb4)
Solutions
- Choose an alias that doesn't collide with any sibling command name or alias.
- Rename the conflicting sibling command if the alias is more important.
- When loading plugins/aliases dynamically, scan program.commands for existing names+aliases before calling .alias().
Example fix
// before (throws: 'run' already a sibling)
program.command('run');
program.command('start').alias('run');
// after
program.command('run');
program.command('start').alias('go'); Defensive patterns
Strategy: validation
Validate before calling
function safeAlias(parent, child, alias) {
const taken = new Set(parent.commands.flatMap(c => [c.name(), ...c.aliases()]));
if (taken.has(alias)) {
throw new Error(`alias '${alias}' conflicts with existing sibling command/alias`);
}
child.alias(alias);
} Prevention
- Maintain a single registry of command names+aliases and check before adding.
- When loading plugins, scan parent.commands for conflicts first.
- Add tests that exercise alias + sibling-command combinations.
When it happens
Trigger: `program.command('run'); program.command('start').alias('run')` — 'run' is already a sibling command name, so the alias collides. Also `cmd.alias('x')` when another sibling already has alias 'x'.
Common situations: Two teams adding overlapping aliases; auto-generated aliases from a config that doesn't check siblings; refactor introducing an alias that clashes with an existing command; plugin loading order making a previously-safe alias now collide.
Related errors
- cannot add command '${newCmd}' as already have command '${ex
- Cannot add option '${option.flags}'${this._name && ` to comm
- Command alias can't be the same as its name
- Command passed to .addCommand() must have a name - specify t
- 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/de4217893cef4995.json.
Report an issue: GitHub.