{"record":{"id":"aa9a316bf0da6184","repo":"python/cpython","slug":"invalid-nargs-value","errorCode":null,"errorMessage":"invalid nargs value","messagePattern":"invalid nargs value","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/argparse.py","lineNumber":711,"sourceCode":"        elif action.nargs == ZERO_OR_MORE:\n            metavar = get_metavar(1)\n            if len(metavar) == 2:\n                result = '[%s [%s ...]]' % metavar\n            else:\n                result = '[%s ...]' % metavar\n        elif action.nargs == ONE_OR_MORE:\n            result = '%s [%s ...]' % get_metavar(2)\n        elif action.nargs == REMAINDER:\n            result = '...'\n        elif action.nargs == PARSER:\n            result = '%s ...' % get_metavar(1)\n        elif action.nargs == SUPPRESS:\n            result = ''\n        else:\n            try:\n                formats = ['%s' for _ in range(action.nargs)]\n            except TypeError:\n                raise ValueError(\"invalid nargs value\") from None\n            result = ' '.join(formats) % get_metavar(action.nargs)\n        return result\n\n    def _expand_help(self, action):\n        help_string = str(self._get_help_string(action))\n        if '%' not in help_string:\n            return self._apply_text_markup(help_string)\n        params = dict(vars(action), prog=self._prog)\n        for name in list(params):\n            value = params[name]\n            if value is SUPPRESS:\n                del params[name]\n            elif hasattr(value, '__name__'):\n                params[name] = value.__name__\n        if params.get('choices') is not None:\n            params['choices'] = ', '.join(map(str, params['choices']))\n\n        t = self._theme","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/argparse.py#L693-L729","documentation":"In HelpFormatter._format_args, after handling the sentinel nargs values ('?', '*', '+', REMAINDER, PARSER, SUPPRESS), the code builds a metavar list using range(action.nargs). If nargs is a float or other non-int (e.g. 2.0 or '2'), range() raises TypeError, which is converted to ValueError('invalid nargs value'). It means the parser was constructed with an unusable nargs.","triggerScenarios":"argparse.add_argument('--x', nargs=1.5); nargs='two' (string); nargs=2.0 (float); a computed nargs like len(items)/2 that yields a float.","commonSituations":"Config-driven CLI builders converting YAML/JSON values where 2 parses as float; arithmetic on nargs counts producing floats; passing '*' vs '*' confusion or the string '3'.","solutions":["Pass an int or one of the documented sentinels: nargs=3, '?', '*', '+'.","Coerce computed values: nargs=int(count).","Validate config-sourced nargs before building the parser: allow only int or the four sentinel strings."],"exampleFix":"# before\nparser.add_argument('--pos', nargs=2.0)  # ValueError: invalid nargs value\n\n# after\nparser.add_argument('--pos', nargs=int(2.0))","handlingStrategy":"validation","validationCode":"NARGS_SENTINELS = {'?', '*', '+'}\n\ndef valid_nargs(v) -> bool:\n    return v in NARGS_SENTINELS or (isinstance(v, int) and not isinstance(v, bool) and v >= 0)","typeGuard":"def is_int_nargs(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool)","tryCatchPattern":null,"preventionTips":["Coerce computed counts with int() before passing as nargs","Whitelist config-sourced nargs values: int or '?', '*', '+'","Build parsers in a try/except ValueError during development to surface config errors early"],"tags":["python","argparse","cli","nargs","validation"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}