ValueError —
Right type, wrong value.
Unlike TypeError, which is about the wrong kind of thing, ValueError means the type is perfectly correct — a string is a string — but its actual content can't be used the way you're trying to use it. Watch an invalid value reach a conversion function on LearnBug and see exactly why it's rejected.
What is ValueError?
Python raises this when a function receives an argument of the correct type, but with a value that's inappropriate for what the function needs to do — int("hello") is a string being passed to int(), which does accept strings, just not ones that don't look like a number.
Why visualization helps
Because the type is correct, this error is easy to miss until runtime — nothing about the code looks structurally wrong. LearnBug shows the actual value flowing into the conversion at the moment it fails, so "this specific string can't become a number" is something you see directly rather than infer from a traceback.
Three ways a value fails validation
Unvalidated user input to int()/float()
Converting text input straight into a number without first checking it's actually numeric — "twenty-five" isn't a valid integer string.
Unpacking the wrong number of values
a, b = [1, 2, 3] — the right-hand side has 3 items but only 2 names to unpack into, a mismatched-count ValueError.
A value outside a mathematically valid domain
math.sqrt(-1) — the type (a number) is right, but negative numbers aren't in the domain of the real square root function.
int("twenty-five") — a non-numeric string
user_input = "twenty-five" — a valid string, correct type
There's nothing wrong with this value as a string. It's a perfectly normal piece of text — the problem only appears once you try to interpret it as a number.
int(user_input) — Python parses the string's characters, looking for digits
int() accepts a string argument fine (passing the type check) — but then it has to actually parse the characters as a base-10 number, and "twenty-five" contains no valid digit sequence.
Parsing fails — int() raises ValueError, naming the exact invalid literal
This is the difference from TypeError: the argument's type was fine, it's specifically the value's content that couldn't be interpreted.
Result: ValueError: invalid literal for int() with base 10: 'twenty-five' ✗
The broken code, and the traceback it produces
user_input = "twenty-five"
age = int(user_input) # not a valid integer string
print(age)Traceback (most recent call last):
File "convert.py", line 2, in <module>
age = int(user_input)
^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'twenty-five'Validate first, or catch the exception
user_input = "twenty-five"
try:
age = int(user_input)
print(age)
except ValueError:
print(f"'{user_input}' is not a valid number")Quick Reference
Frequently asked questions
How is ValueError different from TypeError, exactly?
TypeError means the argument's type itself is wrong — passing a list where a number was needed. ValueError means the type is correct but the specific value is unusable — a string is fine for int() in general, just not this particular string. The distinction matters for choosing what to check or catch.
Should I validate before converting, or just catch the exception?
Both are valid, and Python culture generally favors "easier to ask forgiveness than permission" — attempt the conversion inside a try/except rather than pre-validating with something like .isdigit(), which itself has edge cases (it doesn't handle negative numbers or decimals correctly, for instance).
Why does the unpacking example (a, b = [1, 2, 3]) raise ValueError and not something else?
The list [1, 2, 3] is a perfectly valid iterable (correct type for unpacking) — the problem is specifically that it has 3 values when exactly 2 names were provided to unpack into. That's a value-count mismatch, which Python reports as ValueError: too many values to unpack.
Can I get a more specific error message than Python's default?
Yes — catch the ValueError and raise your own with more context, or validate proactively and raise a custom message before attempting the risky operation. This is especially useful in user-facing code, where "please enter a number" is more actionable than Python's raw traceback text.
Watch the exact value that gets rejected
Paste your code into LearnBug and see conversions succeed or fail live.