python/cpython · error · ArgumentError
invalid %(type)s value: %(value)r
Error message
invalid %(type)s value: %(value)r
What it means
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.
Source
Thrown at Lib/argparse.py:2811
type_func = self._registry_get('type', action.type, action.type)
if not callable(type_func):
raise TypeError(f'{type_func!r} is not callable')
# convert the value to the appropriate type
try:
result = type_func(arg_string)
# ArgumentTypeErrors indicate errors
except ArgumentTypeError as err:
msg = str(err)
raise ArgumentError(action, msg)
# TypeErrors or ValueErrors also indicate errors
except (TypeError, ValueError):
name = getattr(action.type, '__name__', repr(action.type))
args = {'type': name, 'value': arg_string}
msg = _('invalid %(type)s value: %(value)r')
raise ArgumentError(action, msg % args)
# return the converted value
return result
def _check_value(self, action, value):
# converted value must be one of the choices (if specified)
choices = action.choices
if choices is None:
return
if isinstance(choices, str):
choices = iter(choices)
if value not in choices:
args = {'value': str(value),
'choices': ', '.join(repr(str(choice)) for choice in action.choices)}
msg = _('invalid choice: %(value)r (choose from %(choices)s)')
View on GitHub (pinned to bc6749cc3b)
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.
Example fix
# before
def port(s):
return int(s) # 'abc' -> invalid int value: 'abc'
parser.add_argument('-p', type=port)
# after
def port(s):
try:
v = int(s)
except ValueError:
raise argparse.ArgumentTypeError(f'not a valid port: {s!r}')
if not 0 < v < 65536:
raise argparse.ArgumentTypeError(f'port out of range: {v}')
return v
parser.add_argument('-p', type=port) Defensive patterns
Strategy: try-catch
Validate before calling
def make_typed(converter, name):
def typed(s):
try:
return converter(s)
except (ValueError, TypeError):
raise argparse.ArgumentTypeError(
f'invalid {name} value: {s!r}')
return typed
parser.add_argument('-n', type=make_typed(int, 'int')) Try / catch
try:
args = parser.parse_args(argv)
except argparse.ArgumentError as e:
if 'invalid' in str(e) and 'value' in str(e):
print('one or more values failed type conversion; check --help for formats') Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid nargs value
- .__call__() not defined
- invalid option name {option_string!r} for BooleanOptionalAct
- nargs for store actions must be != 0; if you have nothing to
- nargs must be %r to supply const
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/3b7e14fb09cd8949.
Report an issue: GitHub.