Fix ValueError: too many values to unpack (expected 2)
Quick answer
ValueError: too many values to unpack (expected 2) means you tried to assign an iterable with more items than you have variables — for example a, b = (1, 2, 3). Count both sides: the number of targets on the left must match the number of values on the right. The most common cause is looping over a dict directly (for k, v in d) instead of d.items(). Fix it by matching the counts, using d.items(), limiting str.split(sep, maxsplit), or absorbing extras with a starred target like a, b, *rest.
You unpack a value and Python stops you:
ValueError: too many values to unpack (expected 2)Or the mirror version:
ValueError: not enough values to unpack (expected 2, got 1)Both say the same thing in different directions: the number of variables on the left doesn't match the number of values on the right. Python's unpacking is strict — two targets need exactly two values, no more, no fewer.
The fix is almost always one of three things: you miscounted, you're iterating a dict the wrong way, or a string split into more pieces than you expected. This guide covers each, plus the star-unpacking trick that makes the whole class of error go away.
Quick Answer
too many values to unpack (expected 2) means you assigned an iterable with more
items than variables, like a, b = (1, 2, 3). Count both sides — targets must
equal values. The most common cause is for k, v in my_dict (use
my_dict.items()). Fix it by matching counts, limiting str.split(sep, maxsplit), or absorbing extras with a, b, *rest.
TL;DR
- Count both sides — targets on the left must equal values on the right.
for k, v in d:is the classic bug → used.items().- Star-unpack to absorb extras:
a, b, *rest = values. str.split(sep, maxsplit)caps parts so unpacking stays exact.- "not enough values" is the same error in reverse.
- Debug with
print(len(x), x)right before unpacking.
Count Both Sides
Every unpacking assignment has two sides, and their counts must match:
a, b = (1, 2) # ✅ 2 targets, 2 values
a, b = (1, 2, 3) # ❌ 2 targets, 3 values → too many values to unpack
a, b = (1,) # ❌ 2 targets, 1 value → not enough values to unpackThat's the whole rule. Everything below is a case where the right-hand side has a different count than you thought.
Triage by Where the Values Come From
Cause 1: Iterating a dict directly (the #1 case)
Looping over a dict yields its keys, not pairs. Unpacking a key into two variables fails:
scores = {"alice": 90, "bob": 85}
# ❌ iterates keys → "alice" unpacks into k, v → too many values
for k, v in scores:
...
# ✅ iterate key-value pairs
for k, v in scores.items():
print(k, v)Why does it say too many and not not enough? Because the key "alice" is a
5-character string, and unpacking it targets each character — 5 values into 2
variables. A 1-character key would raise not enough instead. Either way, the fix
is .items().
Cause 2: str.split() produced more parts than expected
Text with an unexpected extra separator splits into too many pieces:
line = "key: value: with: colons"
# ❌ splits into 4 parts → too many values
key, value = line.split(":")
# ✅ split only on the first colon — value keeps the rest
key, value = line.split(":", 1) # maxsplit=1
# ✅ or collect the tail into a list
key, *values = line.split(":")split(":", 1)→ at most 2 parts, so 2 targets always fit.key, *values→valuesabsorbs everything after the first part.
This is the top cause when parsing CSV lines, log entries, or KEY=VALUE config.
Cause 3: A function returns a different number of values
def get_point():
return (1, 2, 3) # returns 3 values
# ❌ x, y = get_point() → too many values
x, y = get_point()
# ✅ match the count
x, y, z = get_point()
# ✅ or take the first two, ignore the rest
x, y, *_ = get_point()Check the function's actual return with print(get_point()). A refactor that adds
a return value is a common trigger.
Cause 4: A list whose rows aren't length-2
pairs = [(1, 2), (3, 4, 5)] # one row has 3 items
# ❌ blows up on the second row
for a, b in pairs:
...Inspect the shape before trusting it:
for row in pairs:
print(len(row), row) # find the odd row outThen fix the data, or use a, b, *rest = row if extra columns are legitimate.
Star-Unpacking: The General Fix
The * target absorbs any number of items, so counts never mismatch:
first, *middle, last = [1, 2, 3, 4, 5]
# first=1, middle=[2, 3, 4], last=5
head, *tail = "a,b,c,d".split(",")
# head="a", tail=["b", "c", "d"]
a, b, *_ = get_row() # keep two, discard the rest- Exactly one starred target is allowed per assignment.
- The starred variable always becomes a list (possibly empty).
Real Production Scenarios
| Scenario | Broken | Fixed |
|---|---|---|
| Dict loop | for k, v in d: | for k, v in d.items(): |
| CSV parse | k, v = line.split(",") | k, v = line.split(",", 1) |
| Env line | key, val = s.split("=") | key, *val = s.split("=") |
| Return grew | x, y = f() | x, y, *_ = f() |
enumerate | for i in enumerate(x): a, b = i | for i, val in enumerate(x): |
zip of triples | for a, b in zip(...) | for a, b, c in zip(...) |
| DataFrame rows | for a, b in df.iterrows() (ok: 2) | keep index, row |
Reproduce and Debug
The fastest debug is to print the count and value before the unpacking line:
value = get_something()
print(type(value), len(value), value) # how many items, really?
a, b = valuelen(value) tells you immediately whether the right-hand side matches your two
targets. If value is a string, remember len counts characters — a frequent
surprise when a function returns a string instead of a tuple.
Verification Steps
- The counts match:
len(right_hand_side)equals the number of targets (or you used a*target). - Dict loops use
.items(); the loop runs without error. - Splits that can contain the separator use
maxsplitor a starred target. - Functions return exactly what you unpack (or you absorb extras with
*_). - No row in an iterable has an unexpected length.
Green state: every unpacking site either has matching counts or a single
starred target, and iterating over dicts always goes through .items().
Prevention
- Iterate dicts with
.items()(or.keys()/.values()explicitly). - Use
str.split(sep, maxsplit)whenever the separator can appear in the data. - Reach for
a, b, *restwhen length can vary. - Print
len()and the value when a shape is uncertain. - Keep function return arity stable, or unpack with
*_. - Validate row lengths when parsing external data (CSV, logs).
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
too many values (expected 2) | Right side has 3+ items | Add targets / use *rest |
not enough values (expected 2, got 1) | Right side has too few | Remove a target / check data |
| Fails looping a dict | Iterating keys | for k, v in d.items() |
| Fails on some CSV lines | Extra separators | split(sep, maxsplit) |
| Fails after a refactor | Function return changed | Match count / *_ |
| String, not tuple | len counts characters | Return/parse a tuple |
| Only some rows fail | Inconsistent row lengths | Inspect with print(len, row) |
Related Guides
- Fix AttributeError: 'DataFrame' object has no attribute 'append' after Pandas 2.0
- Fix ModuleNotFoundError: No module named 'dotenv'
- Fix ImportError: cannot import name 'Mapping' from 'collections'
- Fix TypeError: Object of type datetime is not JSON serializable
- Python iterables, iterators, and unpacking explained
External References
- Python — Tuples and sequences (unpacking)
- Python — Starred (extended) unpacking, PEP 3132
- Python — dict.items()
- Python — str.split()
FAQs
Can I use two starred targets to fix it?
No. Only one starred target is allowed per assignment — a, *b, *c = x is a
SyntaxError, because Python couldn't decide how to divide the extras. Use a single
* and slice further if needed.
Does unpacking work on any iterable? Yes — tuples, lists, strings, generators, sets, and more. That generality is why a string unpacks into characters, which surprises people iterating dict keys. The count rule applies to all of them.
Why does a, b = "hi" work but a, b = "hey" fail?
"hi" has exactly two characters, so it unpacks into a="h", b="i". "hey" has
three, so it's too many values. Strings are iterables of characters.
Is *_ different from *rest?
Only by convention. _ signals "I'm ignoring this," but it's still a real list.
*rest keeps the extras for use. Both are valid single starred targets.
How do I unpack nested structures?
Mirror the structure on the left: (a, b), c = ((1, 2), 3). Each level's counts
must match, so a nested mismatch raises the same error at that level.
Key takeaways
- •It means the left side has fewer variables than the right side has values — count both sides.
- •The classic cause is 'for k, v in my_dict' — iterating a dict yields keys, so use my_dict.items().
- •Use a starred target to absorb extras: a, b, *rest = values, or first, *_ = values.
- •For CSV/text, str.split(sep, maxsplit) caps the number of parts so unpacking stays exact.
- •'not enough values to unpack' is the same bug in reverse — too few values for the targets.
- •When unsure, print(len(x), x) before unpacking to see the real shape.
Frequently asked questions
What does ValueError: too many values to unpack (expected 2) mean?
It means an assignment like a, b = something received an iterable with more than two items. Python expected exactly two values to match the two targets, but got more. Count the items on the right-hand side and either add targets, remove items, or use a starred target to absorb the extras.
Why does 'for k, v in my_dict' raise too many values to unpack?
Because iterating a dict directly yields its keys, not key-value pairs. Each key is then unpacked into k and v, which fails unless the key happens to have exactly two elements. Use for k, v in my_dict.items() to iterate key-value pairs correctly.
How do I unpack only the first two values and ignore the rest?
Use a starred target: a, b, *rest = values keeps the extras in rest, and first, second, *_ = values discards them. This works for any iterable longer than the number of named targets, so you never hit too many values to unpack.
How do I fix too many values to unpack when splitting a string?
Limit the split with maxsplit: key, value = line.split(':', 1) splits only on the first colon, so value keeps the rest even if it contains more colons. Alternatively use key, *values = line.split(':') to collect the remaining parts into a list.
What's the difference between too many and not enough values to unpack?
Both are count mismatches. Too many means the right-hand side has more values than targets (a, b = 1, 2, 3). Not enough means it has fewer (a, b = [1], which raises not enough values to unpack, expected 2, got 1). The fix is the same idea: make the counts match.
Why does my function cause too many values to unpack?
Because it returns more values than you unpack. If a function returns three values and you write x, y = func(), Python raises the error. Match the number of targets to the return, or use x, y, *_ = func() to absorb extras you don't need.