tj/commander.js · error · Error
Command passed to .addCommand() must have a name - specify t
Error message
Command passed to .addCommand() must have a name - specify the name in Command constructor or using .name()
What it means
Thrown by Command.addCommand() at lib/command.js:290-293 when the subcommand passed in has an empty `_name`. Commander requires every registered subcommand to be addressable by name (for dispatch, help, conflict detection in _registerCommand), so a nameless Command is rejected up front.
Source
Thrown at lib/command.js:291
*/
showSuggestionAfterError(displaySuggestion = true) {
this._showSuggestionAfterError = !!displaySuggestion;
return this;
}
/**
* Add a prepared subcommand.
*
* See .command() for creating an attached subcommand which inherits settings from its parent.
*
* @param {Command} cmd - new subcommand
* @param {object} [opts] - configuration options
* @return {Command} `this` command for chaining
*/
addCommand(cmd, opts) {
if (!cmd._name) {
throw new Error(`Command passed to .addCommand() must have a name
- specify the name in Command constructor or using .name()`);
}
opts = opts || {};
if (opts.isDefault) this._defaultCommandName = cmd._name;
if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation
this._registerCommand(cmd);
cmd.parent = this;
cmd._checkForBrokenPassThrough();
return this;
}
/**
* Factory routine to create a new unattached argument.
*
* See .argument() for creating an attached argument, which uses this routine toView on GitHub (pinned to ba6d13ddb4)
Solutions
- Pass the name in the constructor: `new Command('deploy')`.
- Or set it before addCommand: `cmd.name('deploy'); program.addCommand(cmd);`.
- If the name is derived dynamically, assert it is a non-empty string before constructing: `if (!name) throw ...`.
Example fix
// before
const sub = new Command(); // no name
program.addCommand(sub);
// after
const sub = new Command('deploy');
program.addCommand(sub); Defensive patterns
Strategy: validation
Validate before calling
function addNamed(program, cmd) {
if (!cmd.name?.() && !cmd._name) {
throw new Error('Cannot add a nameless subcommand');
}
if (!cmd.name()) cmd.name(cmd._name || generatedName);
return program.addCommand(cmd);
} Type guard
import { Command } from 'commander';
function isNamedCommand(v: unknown): v is Command {
return v instanceof Command && typeof v.name() === 'string' && v.name().length > 0;
} Prevention
- Always pass the name to new Command('name') at construction.
- In factories/dynamic loaders, assert cmd.name() is non-empty before addCommand.
- Add a unit test that every registered subcommand has a name.
When it happens
Trigger: `new Command()` with no argument, or `new Command('')`, then `program.addCommand(cmd)`. Also happens when constructing with `.command()` style but forgetting the name, or when the name was meant to be set later via `.name()` but never was.
Common situations: Refactor where a Command was created in a factory function and the name parameter was dropped; copy-paste from `.command('name')` examples into the `new Command()` form; dynamic command construction where the name comes from a config that returned undefined.
Related errors
- cannot add command '${newCmd}' as already have command '${ex
- only the last argument can be variadic '${previousArgument.n
- a default value for a required argument is never used: '${ar
- Unexpected value for event passed to hook : '${event}'. Expe
- Cannot add option '${option.flags}'${this._name && ` to comm
AI-assisted analysis of tj/commander.js@ba6d13ddb4 (2026-08-03).
Data as JSON: /data/errors/5d714f0524122363.json.
Report an issue: GitHub.