ValueError: invalid literal for int() with base 10 — how to fix
Traceback (most recent call last):
File "app.py", line 2, in <module>
age = int(value)
ValueError: invalid literal for int() with base 10: '12.5'
Quick fix: Look at the quoted value in the message. For decimals use int(float(s)); strip whitespace with s.strip(); skip empty strings and header rows; or wrap in try: int(s) except ValueError: to handle bad input.
What it means
int("42") works. int() with a string only accepts optional whitespace, an optional sign, and digits (underscores between digits are allowed, e.g. "1_000"). Anything else raises ValueError, and the message ends with repr() of the bad input. That quoted value is the key to the fix:
| Message ends with | Problem |
|---|---|
'' |
empty string |
'12.5' |
decimal number |
'1,000' |
thousands separator |
'age' |
header row / label |
'0x1f' |
hex, needs a base |
'42abc' |
trailing junk |
Cause 1: the string is a decimal
int("12.5") # ValueError
int(float("12.5")) # 12 (truncates toward zero)
round(float("12.5")) # 12 (banker's rounding)
For money or exact values use decimal.Decimal("12.5").
Cause 2: empty string
Common with input() when the user presses Enter, blank CSV cells, or line.split(",") on a trailing comma.
s = s.strip()
n = int(s) if s else 0
Cause 3: header row or labels in a file
with open("data.csv") as f:
for line in f:
total += int(line.split(",")[1]) # first line is "name,age"
Skip the header, or use the csv module:
import csv
with open("data.csv", newline="") as f:
reader = csv.DictReader(f)
total = sum(int(row["age"]) for row in reader if row["age"].strip())
Cause 4: formatted numbers
int("1,000".replace(",", "")) # 1000
int("$25".lstrip("$")) # 25
For locale-aware parsing ("1.234,5"), use locale.atof after locale.setlocale, or babel.numbers.parse_decimal.
Cause 5: other bases
int("0x1f", 16) # 31
int("0x1f", 0) # 31, base inferred from prefix
int("1010", 2) # 10
Cause 6: hidden characters
Newlines are fine (int("5\n") works), but a BOM, non-breaking space or \x00 is not. Print with repr() to see them:
print(repr(s)) # '\ufeff42'
Open the file with encoding="utf-8-sig" to drop a BOM.
Handling user input robustly
def to_int(s, default=None):
try:
return int(s)
except (TypeError, ValueError):
return default
while True:
try:
age = int(input("Age: "))
break
except ValueError:
print("Please enter a whole number.")
In pandas, use pd.to_numeric(df["col"], errors="coerce") to turn bad values into NaN instead of crashing.
Last updated 2026-11-03.