DEV Community

Yunus Emre Güzel
Yunus Emre Güzel

Posted on Edited on Originally published at blog.emreguzel.ca

ValueError: invalid literal for int() with base 10 (Fix)

Your script runs, then Python stops with this:

ValueError: invalid literal for int() with base 10: '3.50'
Enter fullscreen mode Exit fullscreen mode

You gave int() a string that doesn't look like a whole number. The end of the message shows the exact text Python choked on, in quotes. So the error already tells you what's wrong. Below are the six inputs that cause it most often, and how to fix each one. I ran every example on Python 3.11, 3.12 and 3.14. All three print the same message.

What the Error Means

int(text) turns a string like "42" into the number 42. It takes an optional sign and digits. It also ignores spaces and a newline at either end, so int(" 42\n") works. Anything else breaks it: a decimal point, a comma, a letter, an empty string. Python raises a ValueError for those. Why not a TypeError? Because a string is the right type. This particular value just isn't usable.

The real cause is where the string came from. Text from input(), a file line, a CSV cell, a web form or an API is always text. And text can hold anything.

How to Find the Cause Fast

Look at the quoted text at the end of the message. That's the string that failed. If it might hide odd characters, print it with repr():

print(repr(text))
Enter fullscreen mode Exit fullscreen mode

Then compare what you see with the six cases below.

The Six Causes

1. An Empty String

text = ""                              # for example, the user just pressed Enter
number = int(text)                     # ValueError: invalid literal for int() with base 10: ''
Enter fullscreen mode Exit fullscreen mode

The message ends in : '', with nothing between the quotes. You'll see it when someone hits Enter at an input() prompt. You'll also see it with an empty CSV cell, or when a split line leaves an empty piece. Catch the error, then decide what an empty value should mean:

text = ""
try:
    number = int(text)
except ValueError:
    number = 0                         # or ask again
print(number)
Enter fullscreen mode Exit fullscreen mode

2. A Decimal Number

price = "3.50"
cents = int(price)                     # ValueError: invalid literal for int() with base 10: '3.50'
Enter fullscreen mode Exit fullscreen mode

Odd, but true: int() happily takes the float 3.5 and cuts it to 3. It refuses the string "3.50". So go through a float first. For money, use decimal and skip the rounding surprises:

price = "3.50"
cents = int(float(price) * 100)        # parse as float first
print(cents)

from decimal import Decimal            # exact money maths
print(int(Decimal(price) * 100))
Enter fullscreen mode Exit fullscreen mode

3. A Thousands Separator

population = "1,250,000"
print(int(population))                 # ValueError: invalid literal for int() with base 10: '1,250,000'
Enter fullscreen mode Exit fullscreen mode

Numbers pasted from a web page or spreadsheet often carry commas. Strip them before you convert. Does your data use a space or a dot instead? Remove that one:

population = "1,250,000"
print(int(population.replace(",", "")))
Enter fullscreen mode Exit fullscreen mode

4. A Unit or Symbol Next to the Number

weight = "72kg"
print(int(weight))                     # ValueError: invalid literal for int() with base 10: '72kg'
Enter fullscreen mode Exit fullscreen mode

Values like 72kg, $5 or 50% have characters that aren't digits. Pull the digits out with a regular expression. Or strip the symbol if you know exactly what it is. Check the regex actually found something, since re.search gives back None when it doesn't:

import re

weight = "72kg"
match = re.search(r"\d+", weight)
print(int(match.group()) if match else "no number found")
Enter fullscreen mode Exit fullscreen mode

5. A Number in Another Base

color = "ff"
print(int(color))                      # ValueError: invalid literal for int() with base 10: 'ff'
Enter fullscreen mode Exit fullscreen mode

Unless you say otherwise, int() reads base 10. That's why the message says with base 10. Hex text like "ff" needs the base as a second argument. Use 16 for hex, 2 for binary and 8 for octal:

color = "ff"
print(int(color, 16))                  # tell int() the base: 255
Enter fullscreen mode Exit fullscreen mode

6. A Header or Label Line Mixed In With the Numbers

lines = ["id", "10", "20"]            # the first line is a header, not a number
total = 0
for line in lines:
    total += int(line)                 # ValueError: invalid literal for int() with base 10: 'id'
print(total)
Enter fullscreen mode Exit fullscreen mode

Reading a file line by line? The first line is often a title or header, not data. The message names the culprit, here 'id'. Skip that line. Or let the csv module deal with the header for you:

lines = ["id", "10", "20"]
total = 0
for line in lines[1:]:                 # skip the header
    total += int(line)
print(total)
Enter fullscreen mode Exit fullscreen mode

The General Fix: Validate Before You Convert

If a person typed the text, don't assume it's a number. Keep asking until it is:

while True:
    text = input("Age: ")
    try:
        age = int(text)
        break
    except ValueError:
        print("Please type a whole number, like 25.")
Enter fullscreen mode Exit fullscreen mode

Put only the conversion inside try. That way an unrelated bug won't get swallowed by the same except. And don't rely on text.isdigit() alone. It rejects negatives like "-5", and it says True for some characters that int() can't convert.

The Same Error for float()

float() acts the same way, with a different message: ValueError: could not convert string to float: 'abc'. The causes match too. Think empty strings, a comma as the decimal mark ("3,5"), a unit or symbol, or a header. The fixes above work here as well.

Cleaning Text Before You Convert

A few string methods fix most messy input in one line. strip() trims spaces and newlines from both ends, though int() already ignores those. replace() removes separators. split() cuts a line into pieces, and you convert each piece on its own. A small helper keeps all the cleaning in one place:

def to_int(text, default=None):
    cleaned = text.strip().replace(",", "").replace("_", "")
    try:
        return int(cleaned)
    except ValueError:
        return default

print(to_int("1,250"))      # 1250
print(to_int(""))           # None
print(to_int("abc", 0))     # 0
Enter fullscreen mode Exit fullscreen mode

Python also allows underscores inside a number, so int("1_000") is 1000. The language permits it. Still, a stray underscore in user input is more likely a typo, so the helper removes it. Returning a default instead of raising is a choice, too. Make it only where you know what a bad value should mean for your program.

Quick Reference

Text that failed Fix
'' (empty) Catch the error, or check for an empty string first
'3.50' int(float(text)), or Decimal for money
'1,250,000' text.replace(",", "")
'72kg', '$5' Extract the digits with re.search(r"\d+", text)
'ff' int(text, 16)
'id' or another header Skip the first line, or use csv

The Rule, Stated Once

ValueError: invalid literal for int() with base 10 means the string isn't a plain whole number. The message ends with that exact string, so read it first. Then clean it, convert it the right way, or validate before converting. And wrap only the conversion in try/except ValueError.

Other Python errors with a clear cause are IndexError: List Index Out of Range, TypeError: NoneType Is Not Subscriptable, IndentationError and UnboundLocalError. New to Python? Start with Python for Beginners.

Download the code: the broken and fixed versions of all six causes are on GitHub in Python-projects/Troubleshooting/valueerror-invalid-literal-int. Run any file with python bug.py from inside its folder.

Top comments (0)