{"ecosystem":"npm","package":"commander","version":null,"bugs":[{"id":193,"ecosystem":"npm","package_name":"commander","affected_version":"2.9.0","fixed_version":null,"bug_id":"github:508","title":"git-style subcommands mess up argument order when using boolean flags","description":"**index.js**\r\n\r\n``` js\r\nvar command = require('commander')\r\n\r\nvar cmd = command\r\n  .command('hello', 'description')\r\n  .parse(process.argv)\r\n```\r\n\r\n**index-hello.js**\r\n\r\n``` js\r\nvar command = require('commander')\r\n\r\nvar cmd = command\r\n  .option('--dry-run', 'prints actions, but takes none')\r\n  .parse(process.argv)\r\n\r\nconsole.log('opts', cmd.opts())\r\nconsole.log('args', cmd.args)\r\n```\r\n\r\n**output**\r\n\r\n```\r\n$ node index.js hello 1 2 --dry-run 3 4 5 6\r\nopts { dryRun: true }\r\nargs [ '1', '2', '4', '5', '6', '3' ]\r\n```\r\n\r\nNote how `3` has been shifted to the end. This really messes with you when working with subcommands that expect a specific argument ordering.\r\n\r\n_Found and tested against `commander@2.9.0`_\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/508","labels":["bug"],"created_at":"2026-04-19T04:30:35.290750+00:00","updated_at":"2026-04-19T04:30:35.290750+00:00"},{"id":192,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:552","title":"Cannot pass more than 4 arguments in literal mode","description":"Ref to https://github.com/Unitech/pm2/issues/2064\n\n[This is the main pm2](https://github.com/Unitech/pm2/blob/development/bin/pm2) file on which we use commander.js, but we don't do anything fancy with commander.js\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/552","labels":["bug"],"created_at":"2026-04-19T04:30:35.290338+00:00","updated_at":"2026-04-19T04:30:35.290338+00:00"},{"id":191,"ecosystem":"npm","package_name":"commander","affected_version":"1.0.0","fixed_version":null,"bug_id":"github:553","title":"Command log + option log","description":"When declaring a command with a defined name and declaring option with the same name, it does not works:\n\n``` javascript\nvar program = require('commander');\n\nprogram.version('1.0.0')\n  .option('--log [path]', 'log path')\n\nprogram.command('logs')\n  .alias('log')\n  .action(function() {\n    console.log(program.log);\n  });\n\nprogram.parse(process.argv);\n```\n\n``` bash\n$ node test.js log --log 'test'\n```\n\nIt throws:\n\n```\n/home/unitech/keymetrics/pm2/node_modules/commander/index.js:298\n      args.push(self);\n           ^\n\nTypeError: args.push is not a function\n    at Command.listener (/home/unitech/keymetrics/pm2/node_modules/commander/index.js:298:12)\n    at emitOne (events.js:82:20)\n    at Command.emit (events.js:169:7)\n    at Command.parseOptions (/home/unitech/keymetrics/pm2/node_modules/commander/index.js:699:14)\n    at Command.parse (/home/unitech/keymetrics/pm2/node_modules/commander/index.js:455:21)\n    at Object.<anonymous> (/home/unitech/keymetrics/pm2/test.js:13:9)\n    at Module._compile (module.js:409:26)\n    at Object.Module._extensions..js (module.js:416:10)\n    at Module.load (module.js:343:32)\n    at Function.Module._load (module.js:300:12)\n```\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/553","labels":["bug"],"created_at":"2026-04-19T04:30:35.289973+00:00","updated_at":"2026-04-19T04:30:35.289973+00:00"},{"id":190,"ecosystem":"npm","package_name":"commander","affected_version":"0.0.1","fixed_version":null,"bug_id":"github:561","title":"When arguments() argument is provided, unrecognized flags are silently deleted (no error prints)","description":"I am using commander 2.9.0 (graceful-readlink 1.0.1) on node v4.4.7 (on Windows, running in MSYS2, if it matters).\n\nI run the following test program:\n\n```\nvar commander = require(\"commander\")\n\ncommander\n    .version(\"0.0.1\")\n    .option('-x, --x-flag', 'A flag')\n    .arguments(\"<file>\")\n    .parse(process.argv)\n\nif (commander.xFlag)\n    console.log(\"Got -x\")\nconsole.log(\"Args:\", commander.args)\n```\n\nI find that if I do not supply the `<file>` argument, if I pass a nonsense flag like --nonsense, I will get a nice error message. If I _do_ supply the `<file>` argument, then any nonsense flags included will be silently discarded. Moreover, commander appears to assume each nonsense flag takes one option-argument, and it silently discards that, too. These flags are not appended to commander.args or anything. They just disappear.\n\nA demonstration:\n\n```\n$ node testcommander.js\nArgs: []\n\n$ node testcommander.js -x\nGot -x\nArgs: []\n\n$ node testcommander.js --nonsense -x\n\n  error: unknown option `--nonsense'\n\n$ node testcommander.js -x 1 2 3\nGot -x\nArgs: [ '1', '2', '3' ]\n\n$ node testcommander.js --NONSENSE 1 2 3\nArgs: [ '2', '3' ]\n\n$ node testcommander.js 1 2 3 --NON-SENSE\nArgs: [ '1', '2', '3' ]\n\n$ node testcommander.js 1 2 3 --NON-SENSE QQDFFR -x\nGot -x\nArgs: [ '1', '2', '3' ]\n```\n\n**Expected behavior**: A --flag which is not recognized should result in commander printing an error.\n\nThis is a pretty bad bug. Not only does commander allow something which should be an error, and not only does it do it inconsistently for the same script depending on input, but since commander does this totally silently I cannot even write my own recovery code. If the lost arguments had been appended to `commander.args` at least I could detect it and raise my own error.\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/561","labels":["bug"],"created_at":"2026-04-19T04:30:35.289548+00:00","updated_at":"2026-04-19T04:30:35.289548+00:00"},{"id":189,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:785","title":"Git-style subcommands not working if files are implicit '.js' but command is ran without '.js'","description":"If your command files use the `.js` extension, but you run the command via `node mycommand` instead of `node mycommand.js`, any git-style sub-commands will fail in `Command.prototype#executeSubCommand`\r\n\r\nThis failure is on line 531, column 15 of `index.js`:\r\n```js\r\nvar f = argv[1];\r\n\r\n// ...\r\n\r\nlink = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f;\r\n```\r\n\r\nSpecifically this part is failing:\r\n```js\r\nfs.lstatSync(f)\r\n```\r\n\r\nThis is causing an error because Commander is looking for the file that corresponds to argv[1], so in this specific case, argv[1] doesn't match the actual file name.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/785","labels":["bug"],"created_at":"2026-04-19T04:30:35.289151+00:00","updated_at":"2026-04-19T04:30:35.289151+00:00"},{"id":188,"ecosystem":"npm","package_name":"commander","affected_version":"0.1.0","fixed_version":null,"bug_id":"github:834","title":"Option Coercion - parseInt when combined with a default value will result in NaN","description":"Adding a default value to an option with `parseInt` will result in `NaN` in many cases.\r\n\r\n`parseInt` take two arguments -- `string` and `radix` -- and if you pass a default value to the option, the option will call `parseInt` with the default value as the `radix`.  For example, an option with a default value of 90 and an actual value of 100 will invoke `parseInt(100, 90)`.\r\n\r\nThis is not a problem with `parseFloat` because it only takes one argument.\r\n\r\nSource:\r\n```javascript\r\n#!/usr/bin/env node\r\n\r\n'use strict';\r\n\r\nconst program = require('commander');\r\nconst version = require('./package.json').version;\r\n\r\nprocess.title = 'my-app';\r\n\r\nprogram\r\n  .name('my-app')\r\n  .version(version, '-v, --version');\r\n\r\nprogram\r\n  .command('start')\r\n  .description('start the app')\r\n  .option('-d, --directory <directory>', 'directory for the thing', '/srv')\r\n  .option('-p, --port <port>', 'port number for the thing', parseInt, 8080)\r\n  .action(({ directory, port }) => console.log(directory, port));\r\n\r\nprogram.parse(process.argv);\r\n\r\nif (!program.args.length) program.help();\r\n```\r\n\r\nExpected:\r\n```\r\n$ ./cli.js start --port 80\r\n/srv 80\r\n```\r\n\r\nActual:\r\n```\r\n$ ./cli.js start --port 80\r\n/srv NaN\r\n```\r\n\r\nI'm not sure what the fix should be in this case. Based on the Coercion section of the REAMDE, the way that commander deals with the default value argument is desirable. The `collect` function in particular shows that the default value of an empty array is being used as part of the coercion:\r\n\r\n(reproduced from README)\r\n```javascript\r\nfunction range(val) {\r\n  return val.split('..').map(Number);\r\n}\r\n\r\nfunction list(val) {\r\n  return val.split(',');\r\n}\r\n\r\nfunction collect(val, memo) {\r\n  memo.push(val);\r\n  return memo;\r\n}\r\n\r\nfunction increaseVerbosity(v, total) {\r\n  return total + 1;\r\n}\r\n\r\nprogram\r\n  .version('0.1.0')\r\n  .usage('[options] <file ...>')\r\n  .option('-i, --integer <n>', 'An integer argument', parseInt)\r\n  .option('-f, --float <n>', 'A float argument', parseFloat)\r\n  .option('-r, --range <a>..<b>', 'A range', range)\r\n  .option('-l, --list <items>', 'A list', list)\r\n  .option('-o, --optional [value]', 'An optional value')\r\n  .option('-c, --collect [value]', 'A repeatable value', collect, [])\r\n  .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)\r\n  .parse(process.argv);\r\n\r\nconsole.log(' int: %j', program.integer);\r\nconsole.log(' float: %j', program.float);\r\nconsole.log(' optional: %j', program.optional);\r\nprogram.range = program.range || [];\r\nconsole.log(' range: %j..%j', program.range[0], program.range[1]);\r\nconsole.log(' list: %j', program.list);\r\nconsole.log(' collect: %j', program.collect);\r\nconsole.log(' verbosity: %j', program.verbose);\r\nconsole.log(' args: %j', program.args);\r\n```\r\n\r\nIf this really is desirable, then I think a note about it in the Coercion section is appropriate. It's still possible to use parseInt, you just have to wrap it:\r\n\r\n```javascript\r\n#!/usr/bin/env node\r\n\r\n'use strict';\r\n\r\nconst program = require('commander');\r\nconst version = require('./package.json').version;\r\n\r\nprocess.title = 'my-app';\r\n\r\nprogram\r\n  .name('my-app')\r\n  .version(version, '-v, --version');\r\n\r\nconst int = (value) => parseInt(value);\r\n\r\nprogram\r\n  .command('start')\r\n  .description('start the app')\r\n  .option('-d, --directory <directory>', 'directory for the thing', '/srv')\r\n  .option('-p, --port <port>', 'port number for the thing', int, 8080)\r\n  .action(({ directory, port }) => console.log(directory, port));\r\n\r\nprogram.parse(process.argv);\r\n\r\nif (!program.args.length) program.help();\r\n```","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/834","labels":["bug","docs"],"created_at":"2026-04-19T04:30:35.288560+00:00","updated_at":"2026-04-19T04:30:35.288560+00:00"},{"id":187,"ecosystem":"npm","package_name":"commander","affected_version":"0.0.1","fixed_version":null,"bug_id":"github:843","title":"Regression between v1.16 and v1.17 when no command are passed and '*' is registered","description":"There is a regression in the version v1.17\r\n\r\nSee this sample:\r\n```js\r\nvar program = require(\"commander\");\r\n\r\nprogram\r\n  .version(\"0.0.1\")\r\n  .command(\"*\")\r\n  .description(\"test\")\r\n  .action(function(cmd) {\r\n    cmdValue = cmd;\r\n  });\r\n\r\nprogram.parse(process.argv);\r\n\r\nif (typeof cmdValue === \"undefined\") {\r\n  console.error(\"no command given!\");\r\n} else {\r\n  console.log(\"command:\", cmdValue);\r\n}\r\n```\r\n\r\n## v1.16\r\n```bash\r\n$ node test.js\r\nno command given!\r\n```\r\n\r\n## v1.17\r\n```bash\r\n$ node test.js\r\ncommand: Command {\r\n  commands: [],\r\n  options: [],\r\n  _execs: {},\r\n  _allowUnknownOption: false,\r\n  _args: [],\r\n  _name: '*',\r\n  _noHelp: false,\r\n  parent:\r\n   Command {\r\n     commands: [ [Circular] ],\r\n     options: [ [Object] ],\r\n     _execs: {},\r\n     _allowUnknownOption: false,\r\n     _args: [],\r\n     _name: 'test',\r\n     Command: { [Function: Command] super_: [Object] },\r\n     Option: [Function: Option],\r\n     _version: '0.0.1',\r\n     _versionOptionName: 'version',\r\n     _events:\r\n      { 'option:version': [Function],\r\n        'command:*': [Function: listener] },\r\n     _eventsCount: 2,\r\n     rawArgs:\r\n      [ 'C:\\\\Program Files\\\\nodejs\\\\node.exe',\r\n        'C:\\\\Users\\\\schroeterm\\\\Desktop\\\\test\\\\test.js' ],\r\n     args: [] },\r\n  _description: 'test',\r\n  _argsDescription: undefined }\r\n```\r\n\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/843","labels":["bug"],"created_at":"2026-04-19T04:30:35.288153+00:00","updated_at":"2026-04-19T04:30:35.288153+00:00"},{"id":186,"ecosystem":"npm","package_name":"commander","affected_version":"0.0.1","fixed_version":null,"bug_id":"github:948","title":"Built-in help subcommand does not work with aliased git-style commands","description":"# Example\r\n\r\n```js\r\n#!/usr/bin/env node\r\n\r\nconst program = require('commander');\r\n\r\nprogram\r\n  .version('0.0.1')\r\n  .description('Fake package manager')\r\n  .command('install [name]', 'install one or more packages').alias('i');\r\n\r\nprogram.parse(process.argv);\r\n```\r\nWhen running the built-in help command on the alias (`pm help i`), this happens:\r\n## Expected Behavior\r\nThe alias gets resolved to `install`, and the information is read from `pm-install`\r\n## Actual Behavior\r\nThe command attempts to read `pm-i` and fails, as it does not exist.\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/948","labels":["bug"],"created_at":"2026-04-19T04:30:35.287777+00:00","updated_at":"2026-04-19T04:30:35.287777+00:00"},{"id":185,"ecosystem":"npm","package_name":"commander","affected_version":"2.13.0","fixed_version":null,"bug_id":"github:962","title":"Subcommand destroys ordering of options","description":"Commander.js version: 2.13.0\r\n\r\nThe feature \"subcommand in dedicated binary\" destroys option ordering for boolean longopts. The bug is that, for unknown options, commander always assumes they have an argument. Boolean longopts don't have an argument, so commander assumes the next option to be an argument to the boolean option. Unknown options get sorted to the end of the argument list, so option ordering is nonsensical after the aforementioned wrong assumption has taken place.\r\n\r\nExample:\r\n\r\n```\r\n$ ls\r\nsomecommand              somecommand-subcommand1\r\n```\r\n\r\n\r\nContents of somecommand:\r\n```\r\nprogram.command('subcommand1', 'execute subcommand1').\r\n```\r\n\r\nTriggering the bug:\r\n`$ ./somecommand subcommand1 --bool-option subcommand2 --subcommand2-option subcommand2-argument`\r\n\r\nshould result in \r\n\r\n`./somecommand-subcommand1 --bool-option subcommand2 --subcommand2-option subcommand2-argument`\r\n\r\nbeing called but commander executes\r\n\r\n`./somecommand-subcommand1 subcommand2-argument --bool-option subcommand2`\r\n\r\nThis is a serious bug because the usage output cannot be made correct for the user, it is confusing the user and it results in the program not working without user feedback in combination with bug #961 .\r\nIt also could lead to random logic being executed if the options are implemented in a specific manner in the subcommand.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/962","labels":["bug"],"created_at":"2026-04-19T04:30:35.287322+00:00","updated_at":"2026-04-19T04:30:35.287322+00:00"},{"id":184,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:995","title":"The Command.prototype.parse() method has issues.","description":"This method has the following issues:\r\n\r\n* when registered `subcommand`, thier arguments and options isn't parsed to check valid.\r\n* when registered `action`, `this.parseArgs()` called subcommand without parsing their arguments and options.\r\n\r\nAs a result, this method's arguments are not evaluted correctly in subcommand.\r\nIn the following code expect to occur `error: missing required argument \"file\"` but not now.\r\n\r\n```\r\nparse\r\n  .command('install <file>')\r\n  .parse('node', 'main.js', 'install') // Expect error but not.\r\n```\r\n\r\nAlso now `the required argument` will not correctly work. \r\n[Fix to fail if required arguments don't exist.](https://github.com/tj/commander.js/pull/941)\r\n\r\nSo it seems that this method should be reconsidered fundamentally.\r\n\r\nThank you for the wonderful library.\r\n\r\n# Related \r\n\r\nhttps://github.com/tj/commander.js/pull/941\r\n\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/995","labels":["bug"],"created_at":"2026-04-19T04:30:35.286928+00:00","updated_at":"2026-04-19T04:30:35.286928+00:00"},{"id":183,"ecosystem":"npm","package_name":"commander","affected_version":"0.0.1","fixed_version":null,"bug_id":"github:1032","title":"Passing command option leaves content in args","description":"As [discussed here](https://github.com/tj/commander.js/issues/978#issuecomment-525692913), opening as a new issue.\r\n\r\nI'm trying to find out whether a command has been executed. The simple idea is that if a command is given, it should be executed (and nothing else). If no command is given, the default logic at the bottom should execute (but not otherwise). In all cases, the global option --load should be supported. Here's the test code:\r\n\r\n```js\r\nvar program = require('commander');\r\n\r\nprogram.version('0.0.1').option('-l, --load <name>', 'load something');\r\n\r\nprogram\r\n  .command('doit [id]')\r\n  .description('do something')\r\n  .option('--better', 'do it better')\r\n  .action((id, cmd) => {\r\n    console.log('executing doit action');\r\n    console.log('id is', id);\r\n    console.log('global load option is ', cmd.parent.load);\r\n    console.log('cmd.better is', cmd.better);\r\n  });\r\n\r\nprogram.parse(process.argv);\r\n\r\nif (program.args.length === 0)\r\n  console.log('started without command, executing main logic');\r\n```\r\n\r\n\r\nThis works correctly when I execute like this:\r\n\r\n```shell\r\n➜ node test.js -l loadname doit myid        \r\nexecuting doit action\r\nid is myid\r\nglobal load option is  loadname\r\ncmd.better is undefined\r\n```\r\n\r\nHowever, when I pass the --better option to the command, the whole thing breaks and the \"main logic\" is executed in addition to the command:\r\n\r\n```shell\r\n➜ node test.js -l loadname doit --better myid\r\nexecuting doit action\r\nid is myid\r\nglobal load option is  loadname\r\ncmd.better is true\r\nstarted without command, executing main logic\r\n```\r\n\r\nUnexpectedly, `args` contains information after the action has been executed, *if* the command option `--better` is passed.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1032","labels":["bug"],"created_at":"2026-04-19T04:30:35.286499+00:00","updated_at":"2026-04-19T04:30:35.286499+00:00"},{"id":182,"ecosystem":"npm","package_name":"commander","affected_version":"0.0.1","fixed_version":null,"bug_id":"github:1039","title":"*Bug* When specify none-defined options followed by values don't exit program with error","description":"```js\r\n// File: index.js\r\nconst program = require('commander');\r\n\r\nprogram\r\n  .version('0.0.1')\r\n  .parse(process.argv);\r\n\r\nconst args = program.args;\r\n\r\nconsole.log(args);\r\n```\r\n\r\n```bash\r\n$ node index.js --bug\r\nerror: unknown option '--bug'\r\n\r\n$ node index.js --bug 0\r\nerror: unknown option '--bug'\r\n\r\n$ node index.js --bug 0 1 2 3\r\n[ '1', '2', '3' ]\r\n```\r\n\r\ndependency:\r\n```json\r\n$ cat package.json\r\n{\r\n  \"dependencies\": {\r\n    \"commander\": \"^3.0.1\"\r\n  }\r\n}\r\n```\r\n\r\nExpecting exit code with an error instead of continue of it.\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1039","labels":["bug"],"created_at":"2026-04-19T04:30:35.286099+00:00","updated_at":"2026-04-19T04:30:35.286099+00:00"},{"id":181,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1089","title":"Help option does not display help when using requiredOption","description":"Hi,\r\n\r\nI wanted to have one option required. Once I added one, the help message will no longer show unless you include the required option. I would have expected it to show the help.\r\n\r\nI created some sample code, from one of your samples.\r\n\r\nTest Code:\r\n\r\n```\r\nconst commander = require(\"commander\");\r\nconst program = new commander.Command();\r\n\r\nprogram\r\n  .option(\"-d, --debug\", \"output extra debugging\")\r\n  .requiredOption(\"-s, --small\", \"small pizza size\")\r\n  .option(\"-p, --pizza-type <type>\", \"flavour of pizza\");\r\n\r\nprogram.parse(process.argv);\r\n\r\nif (program.debug) console.log(program.opts());\r\nconsole.log(\"pizza details:\");\r\nif (program.small) console.log(\"- small pizza size\");\r\nif (program.pizzaType) console.log(`- ${program.pizzaType}`);\r\n```\r\n\r\n\r\nOutput:\r\n```\r\n$ node test.js -h\r\nerror: required option '-s, --small' not specified\r\n```\r\nIf I remove the requiredOption I get the expected output:\r\n```\r\n$ node test.js -h\r\nUsage: test [options]\r\n\r\nOptions:\r\n  -d, --debug              output extra debugging\r\n  -s, --small              small pizza size\r\n  -p, --pizza-type <type>  flavour of pizza\r\n  -h, --help               output usage information\r\n```","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1089","labels":["bug"],"created_at":"2026-04-19T04:30:35.285723+00:00","updated_at":"2026-04-19T04:30:35.285723+00:00"},{"id":180,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1153","title":"about commander -h and help command","description":"First, the cli code as:\r\n```javascript\r\nconst cli = require('commander');\r\nconst plugin = require('./commandos/plugin');\r\n\r\ncli.\r\n  command('plugin [command] [pluginName]').\r\n  description(DESCRIPTION.plugin).\r\n  action(plugin);\r\n\r\ncli.\r\n  command('help').\r\n  description(DESCRIPTION.help).\r\n  action(()=>cli.help());\r\n\r\ncli.parse(process.argv);\r\n```\r\n\r\nWhen I type the command as in terminal:\r\n```shell\r\ncli plugin help\r\n```\r\n\r\nit was not run the [plugin] function, I can not get [command] param, it just print help information in the terminal?\r\nit is a bug, right?","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1153","labels":["bug"],"created_at":"2026-04-19T04:30:35.285306+00:00","updated_at":"2026-04-19T04:30:35.285306+00:00"},{"id":179,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1274","title":"TypeError when running nested subcommand","description":"Repo with minimal example code to reproduce: https://github.com/maximilianschmitt/commander-debug\r\n\r\n---\r\n\r\nHi!\r\n\r\nI'm currently developing a CLI where I'm wanting to nest the subcommands.\r\n\r\nI have the following files:\r\n\r\n```\r\ncli/\r\n    hello                \r\n    hello-world          # `hello world`\r\n    hello-world-germany  # `hello world germany`\r\n```\r\n\r\nAnd I'm trying to run them like so:\r\n\r\n```\r\n$ node cli/hello\r\n# Should run cli/hello\r\n\r\n$ node cli/hello world\r\n# Should run cli/hello-world\r\n\r\n$ node cli/hello world germany \r\n# Should run cli/hello-world-germany\r\n```\r\n\r\nI've read that when defining nested subcommands, you need to specify the `executableFile`, so I've done this in `cli/hello`:\r\n\r\n```\r\n#!/usr/bin/env node\r\nconst { program, Command } = require(\"commander\");\r\nconst packageJSON = require(\"../package.json\");\r\n\r\nprogram.version(packageJSON.version);\r\n\r\nconst helloWorld = new Command(\"world\");\r\nhelloWorld.command(\"germany\", \"Saying hello to Germany\", {\r\n  executableFile: \"hello-world-germany\",\r\n});\r\n\r\nprogram.addCommand(helloWorld);\r\n\r\nprogram.parse(process.argv);\r\n```\r\n\r\nHowever, when I run `node cli/hello world germany`, I get a TypeError:\r\n\r\n```\r\n~/Desktop/commander-debug $ node cli/hello world germany\r\ninternal/validators.js:120\r\n    throw new ERR_INVALID_ARG_TYPE(name, 'string', value);\r\n    ^\r\n\r\nTypeError [ERR_INVALID_ARG_TYPE]: The \"path\" argument must be of type string. Received null\r\n    at validateString (internal/validators.js:120:11)\r\n    at Object.extname (path.js:1229:5)\r\n    at Command._executeSubCommand (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:774:46)\r\n    at Command._dispatchSubcommand (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:863:12)\r\n    at Command._parseCommand (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:882:12)\r\n    at Command._dispatchSubcommand (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:865:18)\r\n    at Command._parseCommand (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:882:12)\r\n    at Command.parse (/Users/max/Desktop/commander-debug/node_modules/commander/index.js:717:10)\r\n    at Object.<anonymous> (/Users/max/Desktop/commander-debug/cli/hello:14:9)\r\n    at Module._compile (internal/modules/cjs/loader.js:1138:30) {\r\n  code: 'ERR_INVALID_ARG_TYPE'\r\n}\r\n```\r\n\r\nIs this a bug or am I doing something wrong?\r\n\r\nThanks for your help!","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1274","labels":["bug"],"created_at":"2026-04-19T04:30:35.284701+00:00","updated_at":"2026-04-19T04:30:35.284701+00:00"},{"id":178,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1301","title":"BUG: defining an option which includes `no-` makes the option true by default","description":"**Current Behavior -**\r\nIf we define an option whose name contains `no-` for e.g. `module-no-parse`, it makes the option `true` by default.\r\n\r\n**Expected Behavior -**\r\nIt is supposed to do this only for flags with leading `no-` as mentioned in docs.  https://github.com/tj/commander.js/#other-option-types-negatable-boolean-and-flagvalue\r\n> You can specify a boolean option long name with a leading no- to set the option value to false when used. Defined alone this also makes the option true by default.\r\n\r\n**Steps to reproduce -**\r\nDefine an option whose name includes `no-` e.g. `module-no-parse`. \r\nCheck its default value in the parser.\r\n![Screenshot at 2020-07-16 20-28-38](https://user-images.githubusercontent.com/46647141/87770313-813be300-c83c-11ea-859e-4ad9ac7fc54e.png)\r\n\r\n**Addition Info**\r\nBug found via https://github.com/webpack/webpack-cli/issues/1679","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1301","labels":["bug"],"created_at":"2026-04-19T04:30:35.284252+00:00","updated_at":"2026-04-19T04:30:35.284252+00:00"},{"id":177,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1374","title":"addHelpCommand missing from TypeScript definitions","description":"Hello,\r\n\r\nIt looks the addHelpCommand method definition is missing in the TypeScript definitions file here:\r\nhttps://github.com/tj/commander.js/blob/master/typings/index.d.ts\r\n\r\nIs this a bug?","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1374","labels":["bug"],"created_at":"2026-04-19T04:30:35.283831+00:00","updated_at":"2026-04-19T04:30:35.283831+00:00"},{"id":176,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1402","title":"`command:<name>` event doesn't bubble to the parent","description":"Hey,\r\n\r\nNot sure if I am using this correctly, but it does seem to be a good use case and not far away from working. \r\n\r\nMy program is as follows:\r\n```\r\nconst config = program.commad('config');\r\nconst start = program.command('start');\r\n\r\nprogram.on('command:*', () => /* handle unexpected command */);\r\n\r\nprogram.on('command:config', () => /* never gets called */);\r\n```\r\n\r\nIn the above example, when `config` command is executed, the `command:config` listener never gets executed. \r\n\r\nAfter console logging around the Commander source code, I have found out that the reason this doesn't work is that listener is registered on `parent` (in this context, main program) whereas the `emit` function is called on a subcommand (`config`). \r\n\r\nChanging `this.emit` to `this.parent.emit` fixes it https://github.com/tj/commander.js/blob/master/index.js#L1003\r\n\r\nIs there any way to bubble events up? It seems to be quite natural to listen to `command:<name>` on the main object, otherwise, there's no difference from attaching a listener to `config` vs tweaking action handler.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1402","labels":["bug"],"created_at":"2026-04-19T04:30:35.283398+00:00","updated_at":"2026-04-19T04:30:35.283398+00:00"},{"id":175,"ecosystem":"npm","package_name":"commander","affected_version":"4.0.1","fixed_version":null,"bug_id":"github:1460","title":"Options parsed before validating argument","description":"Hi there,\r\n\r\nThis is a great project, thank you for maintaining this. \r\n\r\nWe're in the process of upgrading from v4.0.1 to v7.0.0 with the new features. We have a small problem whereby options are being parsed before the arguments themselves are validated. \r\n\r\nWe were hoping to be able to continue to listen to `command:*` to detect bad arguments, as we've currently hooked it up to our own suggestion engine to provide \"did you mean\" suggestions for the bad argument. Upgrading to v7.0.0 has broken this functionality for us. \r\n\r\nE.g. \r\n```\r\n$ program bad_argument --help\r\n\r\n# Outputs the help menu instead of complaining that bad_argument is a bad argument\r\n```\r\n\r\nAnother example:\r\n```\r\n$ program lintt --fix\r\n\r\n# Complains that --fix is not a valid option. Instead, we expected `lintt` to be\r\n# detected as a bad argument so we can suggest `lint` to the user.\r\n```\r\n\r\nMinimal reproduction:\r\n```\r\nimport commander from 'commander';\r\n\r\nconst program = new commander.Command();\r\n\r\nprogram.on('command:*', (arg: string) => {\r\n  console.log(`Detected bad arg: ${arg}`);\r\n});\r\n\r\nprogram.command('lint').action(() => {\r\n  console.log('lint');\r\n});\r\n\r\nprogram.parse();\r\n```\r\n\r\nI dug into the source code a bit and think I found it. It appears to be parsing the options and throwing the error first, before reaching the \"command:*\" section. \r\n\r\nhttps://github.com/tj/commander.js/blob/034ad9f326ee2b26001b864adda5fea465ee148b/index.js#L1472\r\n\r\n\r\nIs there a solution or workaround to this that I haven't found? Thanks :). ","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1460","labels":["bug"],"created_at":"2026-04-19T04:30:35.282888+00:00","updated_at":"2026-04-19T04:30:35.282888+00:00"},{"id":174,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1465","title":"Command' is not assignable to type CommanderStatic.Command","description":"I try to create an init command using TypeScript, as follows：\r\n\r\n```ts\r\nimport { Command } from \"commander\";\r\nexport const init = ():Command => {\r\n  const init = new Command(\"init\");\r\n\r\n  init\r\n    .arguments(\"[name]\")\r\n    .option(\"--disable-lint\", \"disable lint\", false)\r\n    .action(async (name = \"\", options) => {\r\n      //  my action\r\n    });\r\n\r\n  return init;\r\n};\r\n```\r\n\r\nBut at last return init, typescript report error:\r\n\r\nTS2322: Type 'import(\"/Users/qishaoxuan/work/leo/node_modules/commander/typings/index\").Command' is not assignable to type 'import(\"/Users/qishaoxuan/work/leo/node_modules/commander/typings/index\").CommanderStatic.Command'.   The types returned by 'version(...)' are incompatible between these types.     Type 'Command' is not assignable to type 'this'.       'Command' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Command'.\r\n\r\n\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1465","labels":["bug"],"created_at":"2026-04-19T04:30:35.282189+00:00","updated_at":"2026-04-19T04:30:35.282189+00:00"},{"id":173,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1480","title":"[Question] How to get option name?","description":"From docs:\r\n\r\n```\r\nprogram\r\n  .option('-d, --debug', 'output extra debugging')\r\n  .option('-s, --small', 'small pizza size')\r\n  .option('-p, --pizza-type <type>', 'flavour of pizza');\r\n\r\nprogram.parse(process.argv);\r\n\r\nconst options = program.opts();\r\nif (options.debug) console.log(options);\r\nconsole.log('pizza details:');\r\nif (options.small) console.log('- small pizza size');\r\nif (options.pizzaType) console.log(`- ${options.pizzaType}`);\r\n```\r\n\r\nso, the question is how do know option `pizza-type` after parse will get from field `pizzaType`? Do commanderjs provide any function to get value `pizzaType` after bind option `.option('-d, --debug', 'output extra debugging')`?\r\n\r\nThanks!","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1480","labels":["bug"],"created_at":"2026-04-19T04:30:35.281683+00:00","updated_at":"2026-04-19T04:30:35.281683+00:00"},{"id":172,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1598","title":"Option.argumentRejected declared but not implemented.","description":"Hi in your typing file your write:\r\n\r\n````typescript\r\n  /**\r\n   * Validation of option argument failed.\r\n   * Intended for use from custom argument processing functions.\r\n   */\r\n  argumentRejected(messsage: string): never;\r\n````\r\n\r\nbut `argumentRejected` do not exist anywhere.\r\n\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1598","labels":["bug"],"created_at":"2026-04-19T04:30:35.281223+00:00","updated_at":"2026-04-19T04:30:35.281223+00:00"},{"id":171,"ecosystem":"npm","package_name":"commander","affected_version":"2.20.0","fixed_version":null,"bug_id":"github:1648","title":"Refactor option value processing to improve maintainability and fix bugs","description":"There is some subtle code in `addOption` which is hard to make sense of, and has some bugs. If is solid on options used once on command line, but from code inspection I was able to reproduce some logic errors affecting repeated options for boolean with a non-boolean default value (bit obscure!) and optional options.\r\n\r\nThe problems have been present for a long time. I was able to reproduce with v2.20.0 and traced code back to at least v1.1.0. The issues have not been generating reports, and the motivation for changing the code is as much to make the code easier to work on as to improve the behaviour.\r\n\r\nhttps://github.com/tj/commander.js/blob/43f4743864e2f670db5eebcf88c92aa4612c54f1/lib/command.js#L515\r\n\r\n","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1648","labels":["bug"],"created_at":"2026-04-19T04:30:35.280786+00:00","updated_at":"2026-04-19T04:30:35.280786+00:00"},{"id":170,"ecosystem":"npm","package_name":"commander","affected_version":"9.1.0","fixed_version":null,"bug_id":"github:1710","title":"9.1.0 - option.conflicts not working","description":"I'm trying to use the option conflicts configuration, but it doesn't appear to catch the conflicts.\r\n\r\n```\r\nconst { program, Option } = require(\"commander\");\r\n\r\nconst handleAction = (command) => {\r\n  const options = program.opts();\r\n  //options.exact && (options.wild || options.all) && console.log(\"conflict\");\r\n  console.log(\r\n    `${command.name()} with options ${JSON.stringify(program.opts())}`\r\n  );\r\n};\r\n//Global options\r\nprogram\r\n  .addOption(\r\n    new Option(\"-a, --all\", \"all wallets\").conflicts([\"exact\", \"wild\"])\r\n  )\r\n  .addOption(\r\n    new Option(\"-x, --exact <name>\", \"exact wallet name\").conflicts([\r\n      \"all\",\r\n      \"wild\",\r\n    ])\r\n  )\r\n  .addOption(\r\n    new Option(\"-w, --wild <partial>\", \"wild card\").conflicts([\"all\", \"exact\"])\r\n  )\r\n  .option(\"-p, --password <password>\");\r\n\r\n//Sub commands\r\nprogram.command(\"claim\").action((options, command) => {\r\n  handleAction(command);\r\n});\r\n\r\nprogram.parse();\r\n\r\n```\r\n\r\nWhen I run with:\r\nnode commands.js claim -a -x OG\r\n\r\nThe result is:\r\nclaim with options {\"all\":true,\"exact\":\"OG\"}\r\n\r\nHave I configured it incorrectly? Also tried specifying just the short names. Same result.\r\n\r\nThanks.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1710","labels":["bug"],"created_at":"2026-04-19T04:30:35.280334+00:00","updated_at":"2026-04-19T04:30:35.280334+00:00"},{"id":169,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:1863","title":".helpOption(false) also disables subcommand help command","description":"In this example, I'd like to disable impilcit help **option** and only leave impicit help **command**.\r\n`test.mjs`:\r\n```\r\n#!/usr/bin/env node\r\nimport { Command } from 'commander';\r\nconst cmd = new Command ();\r\ncmd\r\n   .helpOption (false)\r\n   .command ('meow')\r\n   .option ('-l, [--loud]')\r\n\r\ncmd.parse ();\r\n```\r\nIf I run `test.mjs`, I get \r\n```\r\nUsage: test [command]\r\n\r\nCommands:\r\n  meow [options]\r\n  help [command]  display help for command\r\n```\r\nas expected, but if I run `test.mjs help meow`, I get an error:\r\n\r\n`error: unknown option '--help' // what option, I thought I was calling help command?`,\r\n\r\nwhile expected outcome would be\r\n```\r\nUsage: test meow [options]\r\n\r\nOptions:\r\n  -l, [--loud]\r\n```","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/1863","labels":["bug"],"created_at":"2026-04-19T04:30:35.279868+00:00","updated_at":"2026-04-19T04:30:35.279868+00:00"},{"id":168,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:2021","title":"Exit Code is Zero if Subcommand Killed by Signal","description":"If a subcommand child process is killed by a signal (e.g. `SIGKILL`), then commander will exit with exit code zero. I'm seeing this where OOM was killing the subcommand but commander was exiting with zero.\r\n\r\nRelevant code looks to be here. The arguments to the `close` event are `(code, signal)` and in the case of killed by signal, `code` will be `null`, so `process.exit` gets called with `null` which leads to exiting with zero. Additionally, should the `exitCallback` case (on line 1036) be using `proc.exitCode` instead of `process.exitCode`? The latter doesn't seem correct.\r\n\r\nhttps://github.com/tj/commander.js/blob/4ef19faac1564743d8c7e3ce89ef8d190e1551b4/lib/command.js#L1032-L1038\r\n\r\nPossible fix for the issue could be to bubble up signals, although I'm not sure how to handle the `exitCallback` case then, since AFAIK there's no way to get an exit code for a signal from Node.js (other than mapping it yourself).\r\n\r\n```js\r\nproc.on('close', (code, signal) => {\r\n  if (signal) {\r\n    process.kill(process.pid, signal);\r\n  } else {\r\n    process.exit.bind(process)(code);\r\n  }\r\n});\r\n```\r\n\r\nAlternatively a fixed exit code of 1 could be used in the case of a signal, which would work for the `exitCallback` case. However, that's not desirable since it will hide the underlying exit code from the subcommand.\r\n\r\nManually mapping signals to exit codes might be the simplest way to handle this for both cases.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/2021","labels":["bug"],"created_at":"2026-04-19T04:30:35.279231+00:00","updated_at":"2026-04-19T04:30:35.279231+00:00"},{"id":167,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:2190","title":"Option.fullDescription() does not exist","description":"`Option.fullDescription()` is defined in the TypeScript definition file `index.d.ts`, but it does not exist in the implementation (`Option.js`).\r\nEither fix type definition or add implementation.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/2190","labels":["bug"],"created_at":"2026-04-19T04:30:35.278782+00:00","updated_at":"2026-04-19T04:30:35.278782+00:00"},{"id":166,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:2290","title":"Strange API behaviour for command description","description":"When adding description to command declaration, command does not work.\r\n\r\nWorking code:\r\n\r\n```\r\nprogram.command('analyze')\r\n  .description('Do analyze.')\r\n  .action(() => console.info(\"Hello explain!\");\r\n```\r\nExecute:\r\n```\r\n> node index.js analyze\r\n> Hello explain!\r\n```\r\n\r\nNot working code:\r\n```\r\nprogram.command('analyze', 'Do analyze.')\r\n  .action(() => console.info(\"Hello explain!\");\r\n```\r\nExecute:\r\n```\r\n> node index.js analyze\r\ninternal/modules/cjs/loader.js:892\r\n  throw err;\r\n  ^\r\n\r\nError: Cannot find module 'C:\\Dev\\stuff\\npm-dependency-inspector\\index-analyze'\r\n?[90m    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)?[39m\r\n?[90m    at Function.Module._load (internal/modules/cjs/loader.js:745:27)?[39m\r\n?[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)?[39m\r\n?[90m    at internal/main/run_main_module.js:17:47?[39m {\r\n  code: ?[32m'MODULE_NOT_FOUND'?[39m,\r\n  requireStack: []\r\n}\r\n```\r\n\r\nI spent HOURS to find a way to make commander work for simpliest command. Read all docummentation, tried several versions, and only happy accident helped me - I added description for one command, and do not added to another. So I found, that another command working and this give me a tip.\r\n\r\nI think, when description specified, or command options specified, commander begin interpretate it as executable command. If it is true, then action() should throw error - it is usless for executable command. WTF? Why simple adding description change behaviour totally? And where in documentation this behaviour is specified?","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/2290","labels":["bug"],"created_at":"2026-04-19T04:30:35.278270+00:00","updated_at":"2026-04-19T04:30:35.278270+00:00"},{"id":165,"ecosystem":"npm","package_name":"commander","affected_version":null,"fixed_version":null,"bug_id":"github:2342","title":"copyInheritedSettings and configureOutput have side-effects","description":"Hi - noticed something that maybe isn't desired behaviour with the above two methods. Since `copyInheritedSettings` sets `this._outputConfiguration = sourceCommand._outputConfiguration` and `configureOutput` does `Object.assign(...)` - this means that one command can change another command's settings unexpectedly:\n\n```ts\nimport {program, Command} from 'commander'\n\nconst one = new Command('one')\n  .description('A very very very very very very very very very very very very very very very very very very very very very very very very long description')\n  .action(() => console.log('hi i am one'))\n  .configureOutput({\n    writeOut: str => console.log(str + '🚀🚀🚀🚀'),\n    getOutHelpWidth: () => 70,\n  })\n\nconst two = new Command('two')\n  .copyInheritedSettings(one)\n  .description('Another very very very very very very very very very very very very very very very very very very very very very very very very long description')\n  .action(() => console.log('hi i am two'))\n  .configureOutput({\n    getOutHelpWidth: () => 200,\n  })\n\nprogram\n  .addCommand(one)\n  .addCommand(two)\n\nprogram.parse()\n```\n\nWhen you do `mycommand one --help` it uses 200 for the help width, not 70 as I'd expect. (Note: `mycommand two --help` prints the `🚀🚀🚀🚀` at the bottom, which _is_ correct/expected, IMO).\n\nSuggested solution: use a spread operator in either/both of the methods.","severity":"medium","status":"fixed","source":"github_issues","source_url":"https://github.com/tj/commander.js/issues/2342","labels":["bug"],"created_at":"2026-04-19T04:30:35.277402+00:00","updated_at":"2026-04-19T04:30:35.277402+00:00"}],"total":29,"_cache":"miss"}