tj/commander.js · error · Error

first parameter to parse must be array or undefined

Error message

first parameter to parse must be array or undefined

What it means

Thrown by Command._prepareUserArgs() at lib/command.js:993-995 when the first argument to parse() (argv) is neither undefined nor an array. parse() expects either no argument (use process.argv) or a string array; anything else (a string, an object, a number) is rejected before any slicing/detection logic runs.

Source

Thrown at lib/command.js:994

    let source;
    this._getCommandAndAncestors().forEach((cmd) => {
      if (cmd.getOptionValueSource(key) !== undefined) {
        source = cmd.getOptionValueSource(key);
      }
    });
    return source;
  }

  /**
   * Get user arguments from implied or explicit arguments.
   * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
   *
   * @private
   */

  _prepareUserArgs(argv, parseOptions) {
    if (argv !== undefined && !Array.isArray(argv)) {
      throw new Error('first parameter to parse must be array or undefined');
    }
    parseOptions = parseOptions || {};

    // auto-detect argument conventions if nothing supplied
    if (argv === undefined && parseOptions.from === undefined) {
      if (process.versions?.electron) {
        parseOptions.from = 'electron';
      }
      // check node specific options for scenarios where user CLI args follow executable without scriptname
      const execArgv = process.execArgv ?? [];
      if (
        execArgv.includes('-e') ||
        execArgv.includes('--eval') ||
        execArgv.includes('-p') ||
        execArgv.includes('--print')
      ) {
        parseOptions.from = 'eval'; // internal usage, not documented
      }

View on GitHub (pinned to ba6d13ddb4)

Solutions

  1. Pass an array of strings: `program.parse(['--foo','bar'], { from: 'user' })`.
  2. Or pass nothing to use process.argv: `program.parse()`.
  3. If you have a string, split first: `program.parse(str.split(/\s+/), { from: 'user' })` — but prefer a real shell-tokenizing library to respect quoting.

Example fix

// before (throws)
program.parse('--foo bar');

// after
program.parse(['--foo', 'bar'], { from: 'user' });
Defensive patterns

Strategy: type-guard

Validate before calling

function safeParse(cmd, argv) {
  if (argv !== undefined && !Array.isArray(argv)) {
    throw new TypeError('parse argv must be undefined or string[]');
  }
  return cmd.parse(argv);
}

Type guard

function isArgv(v: unknown): v is string[] | undefined {
  return v === undefined || (Array.isArray(v) && v.every(x => typeof x === 'string'));
}

Prevention

When it happens

Trigger: `program.parse('--foo bar')` (string instead of array), `program.parse({})`, `program.parse(42)`. Also `program.parse(process.argv.slice(2).join(' '))`.

Common situations: Treating argv as a single string and forgetting to split; passing a config object where argv was expected; spread/operator mistakes that collapse the array; porting from a CLI library that accepted a string.

Related errors


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