{"id":"c5c3303591436bc1","repo":"tj/commander.js","slug":"not-a-number-c5c330","errorCode":null,"errorMessage":"Not a number.","messagePattern":"Not a number\\.","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"examples/options-custom-processing.js","lineNumber":14,"sourceCode":"#!/usr/bin/env node\n\n// This is used as an example in the README for:\n//    Custom option processing\n//    You may specify a function to do custom processing of option values.\n\nimport { Command, InvalidArgumentError } from 'commander';\nconst program = new Command();\n\nfunction myParseInt(value) {\n  // parseInt takes a string and a radix\n  const parsedValue = parseInt(value, 10);\n  if (isNaN(parsedValue)) {\n    throw new InvalidArgumentError('Not a number.');\n  }\n  return parsedValue;\n}\n\nfunction increaseVerbosity(dummyValue, previous) {\n  return previous + 1;\n}\n\nfunction collect(value, previous) {\n  return previous.concat([value]);\n}\n\nfunction commaSeparatedList(value) {\n  return value.split(',');\n}\n\nprogram\n  .option('-f, --float <number>', 'float argument', parseFloat)","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/tj/commander.js/blob/ba6d13ddb4243e5913367734f8c159089ffe7834/examples/options-custom-processing.js#L1-L32","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Supply a parseable integer, e.g. `--integer 42`.","If scientific or float input should be accepted, switch the parser from myParseInt to parseFloat or `Number`.","Improve the parser to give a targeted message including the offending value.","Validate upstream (env var, config loader) before invoking the CLI so the option never sees garbage."],"exampleFix":"// before\n.option('-i, --integer <number>', 'integer argument', myParseInt)\n\n// after (accept decimals too)\n.option('-i, --integer <number>', 'numeric argument', (v) => {\n  const n = Number(v);\n  if (Number.isNaN(n)) throw new InvalidArgumentError(`Not a number: '${v}'`);\n  return n;\n})","handlingStrategy":"try-catch","validationCode":"function parseIntegerOption(raw) {\n  const n = parseInt(raw, 10);\n  if (Number.isNaN(n)) {\n    throw new Error(`'${raw}' is not a valid integer for --integer`);\n  }\n  return n;\n}","typeGuard":"const isNumericString = (v: unknown): v is string =>\n  typeof v === 'string' && v.trim() !== '' && Number.isFinite(Number(v));","tryCatchPattern":"try {\n  await program.parseAsync(argv, { from: 'user' });\n} catch (e) {\n  if (e.code === 'commander.invalidArgument') {\n    console.error(`Bad option value: ${e.message}`);\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Pick parseFloat vs parseInt deliberately and document the difference per option.","Surface the offending value in the parser's error message.","In tests, exercise both valid and invalid option values to catch regressions."],"tags":["commander","option-parsing","validation","cli"],"analyzedSha":"ba6d13ddb4243e5913367734f8c159089ffe7834","analyzedAt":"2026-08-03T20:26:04.326Z","schemaVersion":2}