ValueError
Core Python Errors and Exceptions Error explained

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".

GoalBy the end you can read a ValueError message, fix the six most common causes, and validate or raise ValueError in your own code.

Before this lesson: Python Casting, Python Exceptions: try, except, else and finally

2ValueError: diagram

What int(text) acceptsWhat int(text) acceptstextint(text)"42"42" 42 "42 (spaces ignored)"-7"-7"3.5"ValueError"1,200"ValueError"12kg"ValueError""ValueErrorint() accepts any string, but only if its content is a whole number.
Every row is a string, so the type is always fine. Only the content decides between a number and a ValueError, which is the difference between ValueError and TypeError.

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.

Python
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.

Python
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.

Python
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.

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

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

Python
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)
    break

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

Python
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

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.

Interactive example
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.

  1. Line 1Prices arrive as text, and two of them are not valid float strings: "n/a" and "7,50" (a decimal comma).
  2. Line 2-3total accumulates the valid prices and skipped remembers the rejected strings.
  3. Line 5-7For each string the try block attempts float(text) and adds it to the total. Valid strings such as "5" and "12.00" convert fine.
  4. Line 8-10When float() rejects a string it raises ValueError. The except block saves the bad string and prints the message, which includes the exact rejected text in quotes.
  5. 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")
ValueError: invalid literal for int() with base 10: '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")
ValueError: could not convert string to 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()
ValueError: too many values to unpack (expected 2)

✓ 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")
ValueError: list.remove(x): x not in list

✓ 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)
ValueError: max() iterable argument is empty

✓ 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

The 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.

Your code
price_text = "12.50"
price = int(price_text)
total = price * 2
print(total)

2. Predict which values are accepted

Predict the output Easy

Read the code and type exactly what it prints. Remember what int() accepts and what it rejects.

Read this code
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)

2 more exercises → 6 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

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