tj/commander.js · error · InvalidArgumentError

Not a number.

Error message

Not a number.

What it means

Same InvalidArgumentError thrown by a custom option-processing function — here myParseInt is passed as the parser for `-i, --integer <number>` in examples/options-custom-processing.js:14. When the user supplies `--integer abc`, Commander invokes the parser and the `isNaN` branch throws, surfacing as `error: option '-i, --integer <number>' argument 'abc' is invalid.` Note: option errors are wrapped by Commander's addOption handler (command.js:712) which prepends the offending flags.

Source

Thrown at examples/options-custom-processing.js:14

#!/usr/bin/env node

// This is used as an example in the README for:
//    Custom option processing
//    You may specify a function to do custom processing of option values.

import { Command, InvalidArgumentError } from 'commander';
const program = new Command();

function myParseInt(value) {
  // parseInt takes a string and a radix
  const parsedValue = parseInt(value, 10);
  if (isNaN(parsedValue)) {
    throw new InvalidArgumentError('Not a number.');
  }
  return parsedValue;
}

function increaseVerbosity(dummyValue, previous) {
  return previous + 1;
}

function collect(value, previous) {
  return previous.concat([value]);
}

function commaSeparatedList(value) {
  return value.split(',');
}

program
  .option('-f, --float <number>', 'float argument', parseFloat)

View on GitHub (pinned to ba6d13ddb4)

Solutions

  1. Supply a parseable integer, e.g. `--integer 42`.
  2. If scientific or float input should be accepted, switch the parser from myParseInt to parseFloat or `Number`.
  3. Improve the parser to give a targeted message including the offending value.
  4. Validate upstream (env var, config loader) before invoking the CLI so the option never sees garbage.

Example fix

// before
.option('-i, --integer <number>', 'integer argument', myParseInt)

// after (accept decimals too)
.option('-i, --integer <number>', 'numeric argument', (v) => {
  const n = Number(v);
  if (Number.isNaN(n)) throw new InvalidArgumentError(`Not a number: '${v}'`);
  return n;
})
Defensive patterns

Strategy: try-catch

Validate before calling

function parseIntegerOption(raw) {
  const n = parseInt(raw, 10);
  if (Number.isNaN(n)) {
    throw new Error(`'${raw}' is not a valid integer for --integer`);
  }
  return n;
}

Type guard

const isNumericString = (v: unknown): v is string =>
  typeof v === 'string' && v.trim() !== '' && Number.isFinite(Number(v));

Try / catch

try {
  await program.parseAsync(argv, { from: 'user' });
} catch (e) {
  if (e.code === 'commander.invalidArgument') {
    console.error(`Bad option value: ${e.message}`);
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `node options-custom-processing --integer foo` or `-i abc`. Any value that fails parseInt(_, 10) reaches the throw at line 14. Compare with `-f 1e2` which works because that option uses parseFloat, not myParseInt.

Common situations: Confusing parseFloat vs parseInt options in the same program (float accepts scientific/hex-ish, integer rejects them); passing a comma-list where a single integer was expected; aliasing a numeric option to a boolean-looking value.

Related errors


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