ValueError: invalid literal for int() with base 10 in Python
This error occurs when int() receives a string that is not a valid base-10 integer. Validate input before conversion or handle ValueError explicitly with a try/except block.
Root Cause Analysis
This error occurs when Python tries to convert a string into a base-10 integer using the int() constructor, but the provided string contains characters that do not form a valid integer literal.
Cause 1: Non-Digit Characters in String Inputs
The int() constructor parses strings by looking for an optional sign (+ or -) followed by contiguous numeric digits. Passing alphabetic characters ('abc'), alphanumeric IDs ('USR-402'), or symbol-laden strings raises ValueError: invalid literal for int() with base 10.
Cause 2: Unvalidated External Input Boundaries
External data sources—including command-line arguments, interactive prompts from input(), HTTP request query parameters, or environment variables—always arrive as str types. Attempting direct conversion without validation causes application crashes.
Cause 3: Passing Floating-Point String Literals to int()
While int(12.5) successfully truncates a numeric float to 12, string parsing is stricter: int('12.5') raises ValueError because the decimal point . is not an integer digit in base 10.
Cause 4: Empty Strings and Null Placeholders
Empty strings '', whitespace-only strings ' ', or textual representations of missing values like 'None' and 'null' trigger ValueError when passed directly to int().
Reproduction Code (MCVE)
raw_user_input = 'abc'
user_age = int(raw_user_input)
Solution 1: Defensive Parsing with Explicit try/except ValueError
Wrap the parsing call in an explicit try/except ValueError block. Avoid assigning silent default values without logging or raising domain-level errors, as silent fallbacks can mask corrupted input data in production.
raw_user_input = 'abc'
try:
user_age = int(raw_user_input)
except ValueError:
# Log or raise an explicit validation error instead of silently masking
print(f'Validation error: {raw_user_input!r} is not a valid integer age.')
user_age = None
print(f'User age: {user_age}')
Solution 2: Floating-Point Pre-Conversion for Decimal Strings
When the input string may contain decimal values (e.g. '42.8'), parsing depends on developer intent: if converting fractional numbers to truncated integers is desired, parse with float() first before casting to int().
raw_input_decimal = '42.8'
try:
parsed_value = int(float(raw_input_decimal))
except ValueError:
print(f'Invalid numeric value: {raw_input_decimal!r}')
parsed_value = None
print(f'Parsed value: {parsed_value}')
Common Mistakes & Edge Cases
1. The NoneType Trap: int('None') vs int(None)
A frequent source of confusion is the difference between stringified 'None' and the Python singleton None:
int('None')raisesValueError: invalid literal for int() with base 10: 'None'(attempting to parse the text 'None').int(None)raisesTypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'. Always checkif value is not None:before attempting string conversion.
2. The str.isdigit() Limitation with Negative Numbers
Relying on str.isdigit() as a pre-validation guard fails on valid negative integers because '-42'.isdigit() returns False. Use structured try/except ValueError for robust sign handling.
3. Whitespace Handling
int(' 42 ') succeeds because Python automatically strips leading and trailing whitespace. However, internal whitespace such as int('4 2') will raise ValueError.
4. Decimal Strings vs Floats
Remember that int('12.0') raises ValueError, whereas int(float('12.0')) evaluates cleanly to 12.