python/cpython · error · ValueError
invalid nargs value
Error message
invalid nargs value
What it means
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.
Source
Thrown at Lib/argparse.py:711
elif action.nargs == ZERO_OR_MORE:
metavar = get_metavar(1)
if len(metavar) == 2:
result = '[%s [%s ...]]' % metavar
else:
result = '[%s ...]' % metavar
elif action.nargs == ONE_OR_MORE:
result = '%s [%s ...]' % get_metavar(2)
elif action.nargs == REMAINDER:
result = '...'
elif action.nargs == PARSER:
result = '%s ...' % get_metavar(1)
elif action.nargs == SUPPRESS:
result = ''
else:
try:
formats = ['%s' for _ in range(action.nargs)]
except TypeError:
raise ValueError("invalid nargs value") from None
result = ' '.join(formats) % get_metavar(action.nargs)
return result
def _expand_help(self, action):
help_string = str(self._get_help_string(action))
if '%' not in help_string:
return self._apply_text_markup(help_string)
params = dict(vars(action), prog=self._prog)
for name in list(params):
value = params[name]
if value is SUPPRESS:
del params[name]
elif hasattr(value, '__name__'):
params[name] = value.__name__
if params.get('choices') is not None:
params['choices'] = ', '.join(map(str, params['choices']))
t = self._themeView on GitHub (pinned to bc6749cc3b)
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.
Example fix
# before
parser.add_argument('--pos', nargs=2.0) # ValueError: invalid nargs value
# after
parser.add_argument('--pos', nargs=int(2.0)) Defensive patterns
Strategy: validation
Validate before calling
NARGS_SENTINELS = {'?', '*', '+'}
def valid_nargs(v) -> bool:
return v in NARGS_SENTINELS or (isinstance(v, int) and not isinstance(v, bool) and v >= 0) Type guard
def is_int_nargs(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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'.
Related errors
- nargs for store actions must be != 0; if you have nothing to
- nargs must be %r to supply const
- .__call__() not defined
- invalid option name {option_string!r} for BooleanOptionalAct
- unknown parser %(parser_name)r (choices: %(choices)s)
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/aa9a316bf0da6184.
Report an issue: GitHub.