PythonMastery
reference 3 min read · lesson 14 of 45 in Errors

ValueError: invalid literal for int() with base 10

1 · The lesson

read

What 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

python
>>> int("3.14")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '3.14'
python
>>> 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:

python
n = int(float("3.14"))   # 3 (truncates toward zero)

2. Validate user input with try/except:

python
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):

python
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:

python
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 wrap int(request.args["page"]) in a try/except and default to 1.

See Also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code actually did, not just whether a test passed.