{"record":{"id":"bcef824007b0bbdf","repo":"nodejs/node","slug":"bad-command-s","errorCode":null,"errorMessage":"Bad command: %s\n","messagePattern":"Bad command: (.+?)\n","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"tools/install.py","lineNumber":395,"sourceCode":"    subdir_files(options, zoslibinc, 'include/node/zoslib/', wanted_zoslib_headers)\n\ndef run(options):\n  if options.headers_only:\n    if options.command == 'install':\n      headers(options, install)\n      return\n    if options.command == 'uninstall':\n      headers(options, uninstall)\n      return\n  else:\n    if options.command == 'install':\n      files(options, install)\n      return\n    if options.command == 'uninstall':\n      files(options, uninstall)\n      return\n\n  raise RuntimeError('Bad command: %s\\n' % options.command)\n\ndef parse_options(args):\n  parser = argparse.ArgumentParser(\n      description='Install headers and binaries into filesystem')\n  parser.add_argument('command', choices=['install', 'uninstall'])\n  parser.add_argument('--dest-dir', help='custom install prefix for packagers, i.e. DESTDIR',\n                      default=os.getcwd())\n  parser.add_argument('--prefix', help='custom install prefix, i.e. PREFIX',\n                      default='/usr/local')\n  parser.add_argument('--headers-only', help='only install headers',\n                      action='store_true', default=False)\n  parser.add_argument('--root-dir', help='the root directory of source code',\n                      default=os.getcwd())\n  parser.add_argument('--build-dir', help='the location of built binaries',\n                      default='out/Release')\n  parser.add_argument('--v8-dir', help='the location of V8',\n                      default='deps/v8')\n  parser.add_argument('--config-gypi-path', help='the location of config.gypi',","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/install.py#L377-L413","documentation":"tools/install.py run() only handles the commands 'install' and 'uninstall' (each optionally under --headers-only). Any other command string falls through every branch and raises RuntimeError('Bad command: %s').","triggerScenarios":"Calling install.py's run(options) programmatically with options.command set to something other than 'install' or 'uninstall', bypassing the argparse `choices` restriction that normally makes this unreachable from the CLI.","commonSituations":"A wrapper script or build-system integration that constructs options manually and passes a wrong/typo command; legacy callers from before choices were constrained.","solutions":["Pass only 'install' or 'uninstall' as the command.","If calling run() directly, validate options.command against {'install','uninstall'} before invoking.","Drive the tool via its CLI (argparse already restricts choices) rather than calling run() by hand."],"exampleFix":"// before\noptions.command='build'   # run(options) raises 'Bad command'\n// after\noptions.command='install'  # or 'uninstall'","handlingStrategy":"validation","validationCode":"assert options.command in ('install','uninstall'), f'Bad command: {options.command}'","typeGuard":"def is_valid_command(c: str) -> bool:\n    return c in ('install','uninstall')","tryCatchPattern":null,"preventionTips":["Use the CLI entry point so argparse enforces choices.","Validate command against the allowed set before any programmatic call."],"tags":["install","node","api-usage"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}