{"record":{"id":"b598529e36162af0","repo":"python/cpython","slug":"expected-s-argument","errorCode":null,"errorMessage":"expected %s argument","messagePattern":"expected (.+?) argument","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"Lib/argparse.py","lineNumber":2555,"sourceCode":"\n    def _match_argument(self, action, arg_strings_pattern):\n        # match the pattern for this action to the arg strings\n        nargs_pattern = self._get_nargs_pattern(action)\n        match = _re.match(nargs_pattern, arg_strings_pattern)\n\n        # raise an exception if we weren't able to find a match\n        if match is None:\n            nargs_errors = {\n                None: _('expected one argument'),\n                OPTIONAL: _('expected at most one argument'),\n                ONE_OR_MORE: _('expected at least one argument'),\n            }\n            msg = nargs_errors.get(action.nargs)\n            if msg is None:\n                msg = ngettext('expected %s argument',\n                               'expected %s arguments',\n                               action.nargs) % action.nargs\n            raise ArgumentError(action, msg)\n\n        # return the number of arguments matched\n        return len(match.group(1))\n\n    def _match_arguments_partial(self, actions, arg_strings_pattern):\n        # progressively shorten the actions list by slicing off the\n        # final actions until we find a match\n        for i in range(len(actions), 0, -1):\n            actions_slice = actions[:i]\n            pattern = ''.join([self._get_nargs_pattern(action)\n                               for action in actions_slice])\n            match = _re.match(pattern, arg_strings_pattern)\n            if match is not None:\n                result = [len(string) for string in match.groups()]\n                if (match.end() < len(arg_strings_pattern)\n                    and arg_strings_pattern[match.end()] == 'O'):\n                    while result and not result[-1]:\n                        del result[-1]","sourceCodeStart":2537,"sourceCodeEnd":2573,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/argparse.py#L2537-L2573","documentation":"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.","triggerScenarios":"`--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).","commonSituations":"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.","solutions":["Provide the missing value token(s) after the option.","If the value can legitimately be absent, use nargs='?' with a default.","For values starting with '-', use the `--opt=-value` inline form so the value is not mistaken for an option.","For values that look like options (e.g. negative numbers), pass type=int so argparse's negative-number matcher accepts them."],"exampleFix":"# before\nparser.add_argument('--tag')\nparser.parse_args(['--tag'])  # error: expected one argument\n\n# after\nparser.parse_args(['--tag=v1'])  # or ['--tag', 'v1']","handlingStrategy":"validation","validationCode":"def option_has_values(argv, parser):\n    one_val = {s.split('=')[0] for a in parser._actions if a.nargs is None\n               for s in a.option_strings}\n    for i, tok in enumerate(argv):\n        name = tok.split('=', 1)[0]\n        if name in one_val:\n            if '=' in tok:\n                continue\n            if i + 1 >= len(argv) or argv[i + 1].startswith('-'):\n                return tok  # --opt with no following value token\n    return None","typeGuard":null,"tryCatchPattern":"try:\n    args = parser.parse_args(argv)\nexcept argparse.ArgumentError as e:\n    if 'expected' in str(e) and 'argument' in str(e):\n        print('option present but missing its value token(s)')","preventionTips":["Always emit option and value as adjacent tokens when building argv.","Use the '--opt=-value' inline form for values starting with '-'.","Prefer nargs='?' with a default when an option's value is legitimately optional."],"tags":["argparse","cli","nargs","missing-value"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}