{"id":"de4217893cef4995","repo":"tj/commander.js","slug":"cannot-add-alias-alias-to-command-this-nam","errorCode":null,"errorMessage":"cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'","messagePattern":"cannot add alias '(.+?)' to command '(.+?)' as already have command '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/command.js","lineNumber":2285,"sourceCode":"    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    let command = this;\n    if (\n      this.commands.length !== 0 &&\n      this.commands[this.commands.length - 1]._executableHandler\n    ) {\n      // assume adding alias for last added executable subcommand, rather than this\n      command = this.commands[this.commands.length - 1];\n    }\n\n    if (alias === command._name)\n      throw new Error(\"Command alias can't be the same as its name\");\n    const matchingCommand = this.parent?._findCommand(alias);\n    if (matchingCommand) {\n      // c.f. _registerCommand\n      const existingCmd = [matchingCommand.name()]\n        .concat(matchingCommand.aliases())\n        .join('|');\n      throw new Error(\n        `cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`,\n      );\n    }\n\n    command._aliases.push(alias);\n    return this;\n  }\n\n  /**\n   * Set aliases for the command.\n   *\n   * Only the first alias is shown in the auto-generated help.\n   *\n   * @param {string[]} [aliases]\n   * @return {(string[]|Command)}\n   */\n\n  aliases(aliases) {","sourceCodeStart":2267,"sourceCodeEnd":2303,"githubUrl":"https://github.com/tj/commander.js/blob/ba6d13ddb4243e5913367734f8c159089ffe7834/lib/command.js#L2267-L2303","documentation":"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.","triggerScenarios":"`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'.","commonSituations":"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.","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()."],"exampleFix":"// before (throws: 'run' already a sibling)\nprogram.command('run');\nprogram.command('start').alias('run');\n\n// after\nprogram.command('run');\nprogram.command('start').alias('go');","handlingStrategy":"validation","validationCode":"function safeAlias(parent, child, alias) {\n  const taken = new Set(parent.commands.flatMap(c => [c.name(), ...c.aliases()]));\n  if (taken.has(alias)) {\n    throw new Error(`alias '${alias}' conflicts with existing sibling command/alias`);\n  }\n  child.alias(alias);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["commander","alias","conflict","configuration"],"analyzedSha":"ba6d13ddb4243e5913367734f8c159089ffe7834","analyzedAt":"2026-08-03T20:26:04.326Z","schemaVersion":2}