tj/commander.js · error · Error

a default value for a required argument is never used: '${ar

Error message

a default value for a required argument is never used: '${argument.name()}'

What it means

Thrown by Command.addArgument() at lib/command.js:383-391 when a required argument (name in `<>`) is given a defaultValue but no custom parser. A required argument is always supplied by the user at runtime, so its default can never apply — the configuration is contradictory and almost always a mistake (the author likely meant optional).

Source

Thrown at lib/command.js:388

  /**
   * Define argument syntax for command, adding a prepared argument.
   *
   * @param {Argument} argument
   * @return {Command} `this` command for chaining
   */
  addArgument(argument) {
    const previousArgument = this.registeredArguments.slice(-1)[0];
    if (previousArgument?.variadic) {
      throw new Error(
        `only the last argument can be variadic '${previousArgument.name()}'`,
      );
    }
    if (
      argument.required &&
      argument.defaultValue !== undefined &&
      argument.parseArg === undefined
    ) {
      throw new Error(
        `a default value for a required argument is never used: '${argument.name()}'`,
      );
    }
    this.registeredArguments.push(argument);
    return this;
  }

  /**
   * Customise or override default help command. By default a help command is automatically added if your command has subcommands.
   *
   * @example
   *    program.helpCommand('help [cmd]');
   *    program.helpCommand('help [cmd]', 'show help');
   *    program.helpCommand(false); // suppress default help command
   *    program.helpCommand(true); // add help command even if no subcommands
   *
   * @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
   * @param {string} [description] - custom description

View on GitHub (pinned to ba6d13ddb4)

Solutions

  1. Make the argument optional: `.argument('[port]', 'port', 3000)` so the default can apply when omitted.
  2. Or drop the default if the argument truly is required: `.argument('<port>', 'port')`.
  3. If you need both required-ness and a fallback transform, supply a parser as the third arg and the default as the fourth: `.argument('<port>', 'port', Number, 3000)` — though note required+default is still semantically odd.

Example fix

// before (throws)
.argument('<port>', 'port', 3000)

// after (optional, default applies)
.argument('[port]', 'port', 3000)
Defensive patterns

Strategy: validation

Validate before calling

// Reject required+default-without-parser at config-build time
function safeArgument(name, opts) {
  const required = name.startsWith('<');
  if (required && 'default' in opts && typeof opts.parser !== 'function') {
    throw new Error(`required arg '${name}' cannot have a default without a parser`);
  }
}

Prevention

When it happens

Trigger: `.argument('<port>', 'port', 3000)` — three-arg form where the third positional is treated as defaultValue when the second isn't a function. Required (`<port>`) + defaultValue present + no parser => throw.

Common situations: Author intends an optional argument but writes `<>` instead of `[]`; copy-paste from an optional example into a required declaration; mixing up the overloaded third parameter (parser vs default).

Related errors


AI-assisted analysis of tj/commander.js@ba6d13ddb4 (2026-08-03). Data as JSON: /data/errors/c412e805a865563b.json. Report an issue: GitHub.