python/cpython · error · ArgumentError

expected %s argument

Error message

expected %s argument

What it means

Inside _get_values, argparse matches an option's trailing arguments against a regex derived from its nargs pattern; if the pattern cannot match (match is None), it raises ArgumentError with a message keyed to nargs: 'expected one argument' (nargs=None), 'expected at most one argument' (nargs='?'), 'expected at least one argument' (nargs='+'), or 'expected N argument(s)' for integer nargs. It means the option was present but not enough value tokens followed it.

Source

Thrown at Lib/argparse.py:2555

    def _match_argument(self, action, arg_strings_pattern):
        # match the pattern for this action to the arg strings
        nargs_pattern = self._get_nargs_pattern(action)
        match = _re.match(nargs_pattern, arg_strings_pattern)

        # raise an exception if we weren't able to find a match
        if match is None:
            nargs_errors = {
                None: _('expected one argument'),
                OPTIONAL: _('expected at most one argument'),
                ONE_OR_MORE: _('expected at least one argument'),
            }
            msg = nargs_errors.get(action.nargs)
            if msg is None:
                msg = ngettext('expected %s argument',
                               'expected %s arguments',
                               action.nargs) % action.nargs
            raise ArgumentError(action, msg)

        # return the number of arguments matched
        return len(match.group(1))

    def _match_arguments_partial(self, actions, arg_strings_pattern):
        # progressively shorten the actions list by slicing off the
        # final actions until we find a match
        for i in range(len(actions), 0, -1):
            actions_slice = actions[:i]
            pattern = ''.join([self._get_nargs_pattern(action)
                               for action in actions_slice])
            match = _re.match(pattern, arg_strings_pattern)
            if match is not None:
                result = [len(string) for string in match.groups()]
                if (match.end() < len(arg_strings_pattern)
                    and arg_strings_pattern[match.end()] == 'O'):
                    while result and not result[-1]:
                        del result[-1]

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Provide the missing value token(s) after the option.
  2. If the value can legitimately be absent, use nargs='?' with a default.
  3. For values starting with '-', use the `--opt=-value` inline form so the value is not mistaken for an option.
  4. For values that look like options (e.g. negative numbers), pass type=int so argparse's negative-number matcher accepts them.

Example fix

# before
parser.add_argument('--tag')
parser.parse_args(['--tag'])  # error: expected one argument

# after
parser.parse_args(['--tag=v1'])  # or ['--tag', 'v1']
Defensive patterns

Strategy: validation

Validate before calling

def option_has_values(argv, parser):
    one_val = {s.split('=')[0] for a in parser._actions if a.nargs is None
               for s in a.option_strings}
    for i, tok in enumerate(argv):
        name = tok.split('=', 1)[0]
        if name in one_val:
            if '=' in tok:
                continue
            if i + 1 >= len(argv) or argv[i + 1].startswith('-'):
                return tok  # --opt with no following value token
    return None

Try / catch

try:
    args = parser.parse_args(argv)
except argparse.ArgumentError as e:
    if 'expected' in str(e) and 'argument' in str(e):
        print('option present but missing its value token(s)')

Prevention

When it happens

Trigger: `--opt` at end of argv with nargs=None and no following value; `--opt --other value` where the next token looks like an option so cannot serve as the value; nargs=3 with only 2 remaining values; nargs='+' with zero non-option tokens left (note: nargs='*' is the one form that never triggers this).

Common situations: Option moved to the end of a generated command line with its value dropped; a value that itself starts with '-' (e.g. negative number or -f) being consumed as an option; shell quoting bugs eating an argument; users assuming `--opt` alone is valid for a one-value option.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/b598529e36162af0. Report an issue: GitHub.