Python ValueError
1ValueError: overview
A ValueError means a function received a value of the correct type but with content it cannot accept, such as int() given the text "abc".
Before this lesson: Python Casting, Python Exceptions: try, except, else and finally
2ValueError: diagram
3ValueError: explained step by step
A ValueError means a function received a value of the right type but with unsuitable content. int() happily accepts strings, but not the string "abc". The type is fine; the value is the problem. Compare this with a TypeError, where the type itself is wrong, such as adding text to a number.
You will meet ValueError most often when you turn text into numbers (see type casting), unpack a sequence into the wrong number of names, or ask a function to do something it can't do with the data you gave it. Because it is an ordinary exception, you can catch it with except ValueError.
How to read a ValueError message
Traceback (most recent call last):
File "main.py", line 2, in <module>
quantity = int(answer)
ValueError: invalid literal for int() with base 10: 'three'
The last line has two parts: the function that complained (int()) and the exact value it rejected, shown with repr() quotes: 'three'. Those quotes are valuable. If you see '42 apples' or '', you instantly know there is extra text or nothing at all.
Why int() says "invalid literal for int() with base 10"
int() only accepts text that looks like a whole number. Letters, decimal points, commas, units and empty strings are all rejected. Leading and trailing spaces are fine.
for text in ["42", " 42 ", "3.5", "1,200", "12 kg", ""]:
try:
print(repr(text), "->", int(text))
except ValueError as err:
print("ValueError:", err)To read a decimal string use float() first, then int() if you need a whole number. Remove thousands separators with text.replace(",", ""), and use .strip() to clean stray whitespace (see string methods).
Why float() says "could not convert string to float"
float() has the same rule with a different message. A European decimal comma ("1,5") or a currency sign ("$9.99") fails.
for text in ["9.99", "$9.99", "1,5", "abc"]:
try:
print(repr(text), "->", float(text))
except ValueError as err:
print("ValueError:", err)
print(float("$9.99".lstrip("$")))Unpacking: "too many values" and "not enough values"
Unpacking assigns each item of a sequence to one name, so the counts must match.
try:
first, last = "Asha Rao Singh".split()
except ValueError as err:
print("ValueError:", err)
try:
day, month, year = (21, 10)
except ValueError as err:
print("ValueError:", err)
first, *middle, last = "Asha Rao Singh".split()
print(first, middle, last)Count the values on the right, or use a starred name (*middle) to collect the extras.
Why list.remove(x) says "x not in list"
Methods such as remove() and index() raise ValueError when the item isn't there. (A dictionary lookup raises KeyError instead.) Check with in first, as covered in list methods.
cart = ["pen", "book"]
try:
cart.remove("lamp")
except ValueError as err:
print("ValueError:", err)
if "lamp" in cart:
cart.remove("lamp")
print(cart)Other everyday ValueErrors
The same family shows up in the standard library. Each message names its own problem:
import math
from datetime import datetime
attempts = [
lambda: math.sqrt(-9),
lambda: max([]),
lambda: datetime.strptime("21/10/2026", "%Y-%m-%d"),
]
for attempt in attempts:
try:
attempt()
except ValueError as err:
print("ValueError:", err)math.sqrt(-9) fails because real square roots of negatives don't exist (math domain error). max([]) has nothing to compare, so check the list is not empty first. strptime needs a format that matches the text exactly; see the datetime module and math functions.
Handling bad input with try/except ValueError
For user input, don't try to predict every bad string. Attempt the conversion and handle the failure. Here a list stands in for what a user might type (see input and output):
answers = ["abc", "", "-3", "7"]
for answer in answers:
try:
quantity = int(answer)
except ValueError:
print(f"{answer!r} is not a whole number, ask again")
continue
print("Accepted", quantity)
breakAvoid answer.isdigit() as your only check: it returns False for "-3" and "2.5", which are valid numbers.
Raising ValueError yourself
When your own function receives a value that makes no sense, raise a ValueError with a clear message instead of returning a wrong result:
def set_age(age):
if age < 0:
raise ValueError(f"age cannot be negative, got {age}")
return age
try:
set_age(-4)
except ValueError as err:
print("ValueError:", err)Quick reference: ValueError
- How to Convert a String to an Int in Python — Use `int(text)`, for example `int("42")` returns `42`. If the string is not a whole number, such as `"3.7"` o…
- How to Convert a String to a Float in Python — Use `float(text)`, for example `float("3.14")` returns `3.14`. Text that is not a number, such as `"abc"` or …
- How to Convert a String to a Datetime in Python — Use `datetime.strptime(text, format)`, for example `datetime.strptime("2026-03-15", "%Y-%m-%d")`. For ISO 860…
4ValueError: syntax
int(text), float(text) # raise ValueError for bad text
try:
n = int(text.strip())
except ValueError as err:
print(err) # handle bad content
first, last = pair # needs exactly 2 items
if item in items: items.remove(item)
raise ValueError("message") # signal a bad value yourself
5ValueError: run the example
Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.
raw_prices = ["19.99", "5", "n/a", "7,50", "12.00"]
total = 0.0
skipped = []
for text in raw_prices:
try:
total += float(text)
except ValueError as err:
skipped.append(text)
print("ValueError:", err)
print("total:", round(total, 2))
print("skipped:", skipped)Expected outputValueError: could not convert string to float: 'n/a'
ValueError: could not convert string to float: '7,50'
total: 36.99
skipped: ['n/a', '7,50']
7ValueError: how the example works
Hover or tap a step to highlight its lines in the example above.
- Line 1Prices arrive as text, and two of them are not valid float strings:
"n/a"and"7,50"(a decimal comma). - Line 2-3
totalaccumulates the valid prices andskippedremembers the rejected strings. - Line 5-7For each string the
tryblock attemptsfloat(text)and adds it to the total. Valid strings such as"5"and"12.00"convert fine. - Line 8-10When
float()rejects a string it raises ValueError. Theexceptblock saves the bad string and prints the message, which includes the exact rejected text in quotes. - Line 12-13The loop never crashes. The total is 19.99 + 5 + 12.00 = 36.99, rounded to two places, and both bad strings are reported.
8ValueError: common mistakes
Passing a decimal string to int()
✗ Wrong
quantity = int("3.5")✓ Right
quantity = int(float("3.5"))
print(quantity)int() only accepts whole-number text. Convert to a float first, then to an int if you need to drop the decimals. Decide whether to round or truncate.
Converting text with a currency sign
✗ Wrong
price = float("$9.99")✓ Right
price = float("$9.99".replace("$", ""))
print(price)Strip anything that is not part of the number (symbols, spaces, thousands commas) before converting.
Unpacking into too few names
✗ Wrong
first, last = "Asha Rao Singh".split()✓ Right
first, *middle, last = "Asha Rao Singh".split()
print(first, middle, last)The right side has three items. Add a name for each one, or collect the extras with a starred name.
Removing an item that isn't in the list
✗ Wrong
cart = ["pen", "book"]
cart.remove("lamp")✓ Right
cart = ["pen", "book"]
if "lamp" in cart:
cart.remove("lamp")
print(cart)Check membership with in before removing, or catch the ValueError if a missing item is acceptable.
Taking the max() of an empty list
✗ Wrong
scores = []
best = max(scores)✓ Right
scores = []
best = max(scores, default=0)
print(best)There is nothing to compare. Check that the list has items, or give max() a fallback with default=.
9ValueError: exercises
Write your answer, then press Check. The checks run in your browser.
1. Fix the price conversion
Fix the bug Easy ✓ CompletedThe text "12.50" should become the number 12.5 in price, and total should be the cost of 2 items. The code raises a ValueError. Fix the line that converts price_text.
price_text = "12.50"
price = int(price_text)
total = price * 2
print(total)price_text = "12.50"
price = float(price_text)
total = price * 2
print(total)
2. Predict which values are accepted
Predict the output Easy ✓ CompletedRead the code and type exactly what it prints. Remember what int() accepts and what it rejects.
values = ["10", "x", "7.5", " 4 ", "-2"]
total = 0
for v in values:
try:
total += int(v)
except ValueError:
print("bad", repr(v))
print(total)bad 'x'
bad '7.5'
12
2 more exercises → 6 more examples
Questions learners ask
Why does int("3.5") fail when int(3.5) works?
int() has two different jobs. Given a float it truncates the number, which is always possible. Given a string it parses it, and the parser only accepts whole-number text. Use int(float("3.5")) to go from decimal text to an integer.
Should I use isdigit() or try/except to validate numbers?
Prefer try/except ValueError. isdigit() returns False for "-5" and "2.5", which are valid numbers, and it can accept some characters that int() can't parse. Trying the conversion and handling the failure is shorter and always matches what int() really accepts.
What is the difference between ValueError and TypeError?
TypeError means the kind of object is wrong, for example int(None) or "a" + 1. ValueError means the kind is acceptable but this particular value isn't, for example int("abc") or math.sqrt(-1). Check the type for TypeError and the content for ValueError.
Further reading
10Next lesson
Up nextPython AttributeErrorAn AttributeError means you used a dot to reach a variable or method that the object does not have, usually because the…Related:
Python CastingPython Exceptions: try, except, else and finallyPython TypeError: What It Means and How to Fix ItPython KeyError: What It Means and How to Fix It
← Python IndentationError · All Errors and Exceptions lessons · Practise in the IDE