TypeError: not all arguments converted during string formatting
Exception: TypeErrorCategory: runtimeRaised at: the % operator, when the placeholders and the values do not match
What this error means
This message comes from old-style % string formatting, and it means you supplied more values than the format string had placeholders for. Python converted some of them, had values left over, and reported it.
The trap is that % is also the modulo operator. When the left side is a number rather than a string, Python tries numeric modulo first, hits something it cannot do, and falls back to reporting a formatting error — which is why the message sounds like a string problem in code that has no strings in it.
Cause 1 — the left side is a number, not a format string
value = 10 % (2, 3) # meant modulo, but a tuple is not a number
Traceback (most recent call last):
File "demo.py", line 1, in <module>
value = 10 % (2, 3)
~~~^~~~~~~~
TypeError: not all arguments converted during string formatting
More often it is an accidental tuple from a trailing comma — (2,) is a tuple, 2 is a number:
half = 10 % 2, # trailing comma makes this the tuple (0,)
print(half) # (0,) — not what you meant
half = 10 % 2 # 0
Cause 2 — more values than placeholders
print("%s scored" % ("Asha", 91)) # one %s, two values
Traceback (most recent call last):
File "demo.py", line 1, in <module>
print("%s scored" % ("Asha", 91))
~~~~~~~~~~~~^~~~~~~~~~~~~~
TypeError: not all arguments converted during string formatting
One placeholder, two values: Asha fills %s, and 91 has nowhere to go. Match the counts:
print("%s scored %d" % ("Asha", 91)) # two placeholders, two values
print(f"{name} scored {score}") # or drop % formatting entirely
Cause 3 — a bare % in the text
A literal percent sign inside a %-formatted string is read as the start of a placeholder. Escape it by doubling:
print("Progress: %d%%" % 80) # Progress: 80%
print("Progress: %d%" % 80) # ValueError: incomplete format
The fix: stop using % formatting
Every one of these bugs disappears with f-strings, which have been in Python since 3.6 and are both faster and easier to read. There is no placeholder to count and no tuple to get wrong:
name, score, rate = "Asha", 91, 80
print("%s scored %d (%d%%)" % (name, score, rate)) # old, brittle
print(f"{name} scored {score} ({rate}%)") # same output, no counting
print(f"rate = {rate / 100:.1%}") # formatting specs work too
How to debug it
- Check the left side of the
%. If it is not a string, you are not formatting at all — you are doing modulo, and the error is misleading. - Look for a trailing comma.
10 % 2,is a tuple, and a tuple on the right of%means 'format arguments'. - Count the placeholders in the format string and the values in the tuple. The numbers must match exactly.
- Double any literal
%in the text to%%. - Convert the line to an f-string. It removes the whole class of bug rather than fixing this one instance.
Related messages worth knowing
- ValueError: invalid literal for int() — the other error formatting and conversion go wrong with.
- can only concatenate str (not "int") to str — the + version of the same mixing problem.
- TypeError: the parent guide — the famous wordings decoded together.
🇮🇳 Hindi में समझें
TypeError: not all arguments converted during string formatting purane % style formatting se aata hai, aur iska matlab hai aapne placeholders से ज़्यादा values दे दीं. Sabse confusing baat: % Python me modulo operator bhi hai. Agar % ke left side me string ki jagah number hai, to Python pehle modulo karne ki koshish karta hai aur yahi error de deta hai — bhale hi code me koi string na ho. Common wajah: trailing comma (10 % 2, ek tuple ban jata hai), ya ek %s ke saath do values. Sabse acha fix: % formatting chhod do aur f-string use karo — f"{name} scored {score}". Isme na placeholder गिनना hai, na tuple ka jhanjhat.