{"record":{"id":"3b7e14fb09cd8949","repo":"python/cpython","slug":"invalid-type-s-value-value-r","errorCode":null,"errorMessage":"invalid %(type)s value: %(value)r","messagePattern":"invalid (.+?) value: %\\(value\\)r","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"Lib/argparse.py","lineNumber":2811,"sourceCode":"        type_func = self._registry_get('type', action.type, action.type)\n        if not callable(type_func):\n            raise TypeError(f'{type_func!r} is not callable')\n\n        # convert the value to the appropriate type\n        try:\n            result = type_func(arg_string)\n\n        # ArgumentTypeErrors indicate errors\n        except ArgumentTypeError as err:\n            msg = str(err)\n            raise ArgumentError(action, msg)\n\n        # TypeErrors or ValueErrors also indicate errors\n        except (TypeError, ValueError):\n            name = getattr(action.type, '__name__', repr(action.type))\n            args = {'type': name, 'value': arg_string}\n            msg = _('invalid %(type)s value: %(value)r')\n            raise ArgumentError(action, msg % args)\n\n        # return the converted value\n        return result\n\n    def _check_value(self, action, value):\n        # converted value must be one of the choices (if specified)\n        choices = action.choices\n        if choices is None:\n            return\n\n        if isinstance(choices, str):\n            choices = iter(choices)\n\n        if value not in choices:\n            args = {'value': str(value),\n                    'choices': ', '.join(repr(str(choice)) for choice in action.choices)}\n            msg = _('invalid choice: %(value)r (choose from %(choices)s)')\n","sourceCodeStart":2793,"sourceCodeEnd":2829,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/argparse.py#L2793-L2829","documentation":"In _get_value, argparse calls the action's type callable on the raw string; if the callable raises ArgumentTypeError its message is used directly, but if it raises TypeError or ValueError (the typical case for built-ins like int('abc')) argparse wraps it in ArgumentError formatted as 'invalid <typename> value: <raw>'. The type name is taken from the callable's __name__ or its repr.","triggerScenarios":"add_argument('-n', type=int) with input 'abc' (int raises ValueError); a type=lambda s: complex(s) receiving an empty string; passing type=open with a nonexistent path (OSError propagates uncaught — different failure); a custom converter whose internals raise TypeError instead of ArgumentTypeError.","commonSituations":"Free-text CLI input that must be numeric or a date; environment-variable-derived arguments holding garbage; custom type functions that let ValueError leak instead of raising argparse.ArgumentTypeError with a friendly message.","solutions":["Pass a value the type callable can convert (e.g. a valid integer for type=int).","In custom type functions, catch conversion errors and raise argparse.ArgumentTypeError('clear message') so users see your text, not 'invalid ... value'.","If the argument may legitimately be absent or empty, add nargs='?' plus a default so the converter is not called on junk."],"exampleFix":"# before\ndef port(s):\n    return int(s)  # 'abc' -> invalid int value: 'abc'\nparser.add_argument('-p', type=port)\n\n# after\ndef port(s):\n    try:\n        v = int(s)\n    except ValueError:\n        raise argparse.ArgumentTypeError(f'not a valid port: {s!r}')\n    if not 0 < v < 65536:\n        raise argparse.ArgumentTypeError(f'port out of range: {v}')\n    return v\nparser.add_argument('-p', type=port)","handlingStrategy":"try-catch","validationCode":"def make_typed(converter, name):\n    def typed(s):\n        try:\n            return converter(s)\n        except (ValueError, TypeError):\n            raise argparse.ArgumentTypeError(\n                f'invalid {name} value: {s!r}')\n    return typed\n\nparser.add_argument('-n', type=make_typed(int, 'int'))","typeGuard":null,"tryCatchPattern":"try:\n    args = parser.parse_args(argv)\nexcept argparse.ArgumentError as e:\n    if 'invalid' in str(e) and 'value' in str(e):\n        print('one or more values failed type conversion; check --help for formats')","preventionTips":["Wrap custom converters so they raise argparse.ArgumentTypeError with actionable messages instead of leaking ValueError.","Document the expected format next to each typed option via the help string and metavar.","Use type=str.lower / str.strip before stricter converters to reduce user-error surface."],"tags":["argparse","cli","type-conversion","invalid-value"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}