How to Read a Python Error Message
A guide to understanding Python tracebacks and the most common beginner errors, with tested examples from the official Python documentation.
A Python error message looks intimidating the first few times you see one, mostly because of the block of text called a "traceback." Once you know what each part means, most error messages actually tell you exactly what went wrong and where.
The two kinds of errors
The official Python tutorial separates errors into two categories. Syntax errors happen when Python can't even understand your code's structure, for example a missing colon:
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^^^^^
SyntaxError: invalid syntax
The little arrow (^^^^^) points at roughly where Python got confused, though the tutorial notes this isn't always the exact spot that needs fixing. In this example, the real issue is the missing colon right before print.
Exceptions happen when your code is structurally valid Python but something goes wrong while it's actually running. This is the category you'll hit far more often as a beginner.
Reading a traceback from the bottom up
The single most useful habit for reading Python errors: read the last line first, then work upward only if you need more context. The last line always has two parts: the exception type, and a message describing what happened.
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
10 * (1/0)
ZeroDivisionError: division by zero
ZeroDivisionError: division by zero tells you immediately what happened: you divided by zero. The lines above it (the "traceback") show you the path the code took to get there, which matters more once your program has multiple functions calling each other, but for a single line like this, the last line already has your answer.
Here are the four errors a beginner runs into constantly, each one tested directly:
>>> n
NameError: name 'n' is not defined
You tried to use a variable that was never created, often because of a typo in the name or because you ran a later cell/line before the one that defines it.
>>> '2' + 2
TypeError: can only concatenate str (not "int") to str
You tried to combine two different, incompatible types. Here, Python will not automatically decide whether '2' + 2 should become '22' or 4, so it raises an error and makes you choose with an explicit conversion.
>>> 10 * (1/0)
ZeroDivisionError: division by zero
Exactly what it says: a division where the bottom number was zero.
>>> word = "Python"
>>> word[42]
IndexError: string index out of range
You asked for a position in a string (or list) that doesn't exist. "Python" only has 6 characters (positions 0 through 5), so asking for position 42 fails.
Handling errors instead of crashing
Once you understand what an error means, you can decide whether your program should catch it and keep running, using try and except. The official tutorial's example for asking a user for a number demonstrates the pattern:
while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
The try block runs first. If it raises a ValueError (which happens if the user types something that isn't a number), the except block catches it and the loop asks again instead of crashing the whole program.
You can also add an else clause, which runs only if no exception occurred, and a finally clause, which always runs no matter what. Running this tested example shows the difference clearly:
def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is", result)
finally:
print("executing finally clause")
divide(2, 1)
divide(2, 0)
The output is:
result is 2.0
executing finally clause
division by zero!
executing finally clause
divide(2, 1) succeeds, so the else block runs ("result is 2.0"), and finally always runs after it. divide(2, 0) triggers the except block instead ("division by zero!"), and finally still runs regardless of which path was taken.
A practical reading order for any error
- Read the last line: exception type, then message.
- If the message alone doesn't make sense, look at the specific line of your code shown just above it; that's where the problem occurred.
- If there are multiple "File" entries stacked in the traceback, the bottom-most one is usually where the actual problem is, and the ones above it just show which function called which.
- Decide: is this a bug to fix, or an expected possibility you should catch with
try/except?
Key takeaways
- Syntax errors mean Python can't parse your code at all; exceptions mean valid code failed while running.
- Always read a traceback's last line first: it names the exception type and gives a specific message.
NameError,TypeError,ZeroDivisionError, andIndexErrorcover most beginner mistakes, and each one points to a specific, fixable cause.- Use
try/exceptto handle errors you expect might happen (like invalid user input) instead of letting them crash your program. finallyalways runs, whether thetryblock succeeded or failed, which makes it useful for cleanup code.