ValueError: invalid literal for int() with base 10
1 · The lesson
readWhat this error means
You passed int() a string that isn't a valid base-10 integer. int() is strict: it accepts an optional leading sign and decimal digits with optional surrounding whitespace — nothing else. Decimal points, letters, commas, currency symbols, and empty strings all fail.
When you see it
>>> int("3.14") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: '3.14'
>>> int("twenty") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'twenty'
Why it happens
int(s) does not parse decimals or scientific notation. "3.14" looks like a number to a human but contains a ., so Python refuses. Empty strings, whitespace-only strings, and strings with thousands separators ("1,000") all fail for the same reason.
How to fix it
1. If the string may have a decimal, go via float:
n = int(float("3.14")) # 3 (truncates toward zero)
2. Validate user input with try/except:
raw = input("age? ") try: age = int(raw) except ValueError: print("Please enter a whole number.")
3. Pre-check with .isdigit() (only works for non-negative integers, no whitespace):
if raw.strip().lstrip("-").isdigit(): age = int(raw)
setup added so this can run · defines raw
# Lightweight mock for objects whose attributes/methods aren't critical class _AutoMock: def __init__(self, name='mock'): self._name = name def __getattr__(self, k): return _AutoMock(self._name + '.' + k) def __call__(self, *a, **kw): print('-> ' + self._name + '() called') return _AutoMock(self._name + '()') def __repr__(self): return '<mock ' + self._name + '>' def __str__(self): return '<mock ' + self._name + '>' def __bool__(self): return True def __iter__(self): return iter([]) def __len__(self): return 0 def __getitem__(self, k): return _AutoMock(self._name + '[...]') def __setitem__(self, k, v): pass def __enter__(self): return self def __exit__(self, *a): return False async def __aenter__(self): return self async def __aexit__(self, *a): return False def __add__(self, o): return self def __radd__(self, o): return self def __sub__(self, o): return self def __mul__(self, o): return self def __rmul__(self, o): return self def __truediv__(self, o): return self def __eq__(self, o): return isinstance(o, _AutoMock) def __hash__(self): return hash(self._name) def __lt__(self, o): return True def __le__(self, o): return True def __gt__(self, o): return False def __ge__(self, o): return False def __mro_entries__(self, bases): return (object,) raw = _AutoMock('raw')
4. Strip thousands separators before parsing:
price = int("1,000".replace(",", "")) # 1000
When you'd actually see this in real code
- Reading numbers from a CSV column where one row contains
"N/A"or an empty cell. - Accepting user input from
input()or a web form without validation — users type"twenty","3.5", or just press enter. - Parsing query string parameters like
?page=abc: always wrapint(request.args["page"])in atry/exceptand default to1.
Related errors
- ValueError: too many values to unpack
- ValueError: not enough values to unpack
- IndexError: string index out of range
See Also
- All Python errors — the full index, by type and by when it happens.
- Type conversion cheat sheet
- Handling user input tutorial
Practice this
on practicepython.inShort exercises that run in your browser and tell you what your code actually did, not just whether a test passed.