ValueError

The type is fine but this particular value is not — int('abc'), unpacking three items into two names, math.sqrt(-1).

InheritsBaseException›Exception›ValueError
Type / value exceptionPython 3 (all)Live demo
ValueError(*args)
Raised by
int('abc'), a, b = [1, 2, 3], list.remove(x), math.sqrt(-1)
Message
describes the value: invalid literal for int() with base 10: 'abc'
Quick fix
validate first, or try/except ValueError around the conversion
Watch out
int('3.5') fails — use int(float(s)) or round(float(s))

Demo

Live evaluation
Convert text with int(). Surrounding whitespace and _ between digits are allowed; a decimal point is not.
Try:
Inputs
textstrtext to convert
Code
int('42')
Result
42

In Trigger, ' -7 ' and '1_000' convert fine but '3.5' does not: int() of a str accepts only an integer literal. In Handle, note the two unpacking messages — too many values says what it expected, not enough values also says how many it got. In Raise, a str input never reaches your ValueError: 0 <= 'half' fails first with a TypeError.

Constructor

NameTypeRequiredDescription
*argsobjectnoUsually one message string describing the bad value. Stored in e.args.

Attributes

AttributeTypeMeaning
argstupleThe constructor arguments — normally a 1-tuple holding the message.
__cause__BaseException | NoneSet by raise ValueError(…) from e — keeps the original low-level error attached.
__notes__list[str]Extra context added with e.add_note() (Python 3.11+), e.g. the line number of the bad record.

Common patterns

Parse or fall back
Conversions of outside text are the classic EAFP case: try the conversion, handle the bad value.
def parse_int(text, default=None):
    try:
        return int(text)
    except ValueError:
        return default
Validate arguments and say why
Raise ValueError from your own functions when the value is outside what you accept. Put the offending value in the message.
def set_port(port):
    if not 0 < port < 65536:
        raise ValueError(f'port must be 1-65535, got {port}')
    return port
Report the bad record, keep the cause
When parsing many lines, re-raise with context. from e keeps the original error as __cause__ in the traceback.
def load(lines):
    rows = []
    for n, line in enumerate(lines, 1):
        try:
            name, qty = line.split(',')
            rows.append((name, int(qty)))
        except ValueError as e:
            raise ValueError(f'line {n}: {line!r}') from e
    return rows
Enum lookup for fixed choices
Enum(value) raises ValueError for an unknown value — a ready-made validator for mode names and status codes.
from enum import Enum

class Mode(Enum):
    READ = 'r'
    WRITE = 'w'

mode = Mode('r')

Examples

1. int() of a decimal string
int('3.5')
Returns
ValueError: invalid literal for int() with base 10: '3.5'
2. Fix: through float()
int(float('3.5'))
Returns
3
3. Empty input
float('')
Returns
ValueError: could not convert string to float: ''
4. Too many values to unpack
a, b = [1, 2, 3]
Returns
ValueError: too many values to unpack (expected 2)
5. Not enough values to unpack
x, y, z = 'ab'
Returns
ValueError: not enough values to unpack (expected 3, got 2)
6. Removing a missing item
[1, 2].remove(3)
Returns
ValueError: list.remove(x): x not in list
7. math domain error
import math math.sqrt(-1)
Returns
ValueError: math domain error
8. Impossible date
from datetime import date date(2024, 2, 30)
Returns
ValueError: day is out of range for month

Pitfalls

1. Looping over a dict with two names
Iterating a dict yields only keys. Unpacking a key like 'id' into k, v tries to split the string — too many or not enough values, depending on its length.
for k, v in d
d = {'a': 1, 'b': 2}
[k + str(v) for k, v in d]
ValueError: not enough values to unpack (expected 2, got 1)
d.items()
d = {'a': 1, 'b': 2}
[k + str(v) for k, v in d.items()]
['a1', 'b2']
2. except ValueError misses None
int(None) is a TypeError, not a ValueError. A parser that may receive None (missing field, empty cell) must catch both.
except ValueError
def parse(x):
    try:
        return int(x)
    except ValueError:
        return 0

parse(None)
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
except (TypeError, ValueError)
def parse(x):
    try:
        return int(x)
    except (TypeError, ValueError):
        return 0

parse(None)
0
3. list.remove() of an item that may be absent
remove() raises when the item is not there, unlike set.discard(). Check membership first, or catch the ValueError.
remove blindly
tags = ['new']
tags.remove('sale')
tags
ValueError: list.remove(x): x not in list
check first
tags = ['new']
if 'sale' in tags:
    tags.remove('sale')
tags
['new']

When to use

Use it
  • An argument has the right type but is out of range or malformed
  • Parsing user input or file data that may not match the expected format
  • Rejecting an unknown option name or mode string
Reach for something else
  • The argument is the wrong type entirely → TypeError
  • A key or index is missing from a container → KeyError / IndexError
  • Validating many fields at once → collect the problems, then raise one error listing them all

Notes

CPython impl
int() of a str: Objects/longobject.c PyLong_FromString — the message embeds repr() of the input, cut to 200 characters
Subclasses
UnicodeError (and its encode/decode/translate subclasses), json.JSONDecodeError, io.UnsupportedOperation — except ValueError catches them all
Digit limit
int() refuses decimal strings over 4300 digits with a ValueError (limit introduced in Python 3.11 and backported to older security releases; sys.set_int_max_str_digits() changes it)
Rule of thumb
Wrong kind of object → TypeError. Right kind, unacceptable value → ValueError.

FAQ

Ask whether any value of this type could work. If no — a list where a number is needed, None — it is a TypeError. If some values of the type work but this one does not — int('abc'), math.sqrt(-1), a negative size — it is a ValueError. int() shows both: int(None) raises TypeError, int('abc') raises ValueError.