TL;DR:
Read a Python traceback from the bottom: the last line names the error type and says what went wrong.
The lines above it show where, with the file, the line number and the code, ending at the line that failed.
If the message does not make sense, search for the error type plus the key words, and check for a typo first.
A wall of red text appears and your stomach drops. Error messages look like an attack, but they are the opposite: the computer is telling you, as exactly as it can, what it could not do and where. Learning to read them is one of the quickest ways to get better at programming.
The idea in plain words
When Python hits a problem it cannot recover from, it prints a traceback. It shows the chain of function calls that led to the problem, ending with the error type and a message. The most useful information is at the bottom, so start there.
Why the bottom first
The traceback is printed in the order the calls were made, so the line that actually failed comes last. The last line tells you what kind of error it was, and the lines just above it show where. Earlier lines show how the program got there, which matters only if the failing line is inside a function and you need to know who called it.
Worked example: a traceback for a NameError
Here is a short program saved as stats.py. It should print the average of three numbers.
def average(numbers):
total = sum(numbers)
return totl / len(numbers)
print(average([2, 4, 6]))Running it prints the following. The folder in your file path will differ.
Traceback (most recent call last):
File "stats.py", line 5, in <module>
print(average([2, 4, 6]))
File "stats.py", line 3, in average
return totl / len(numbers)
NameError: name 'totl' is not definedRead the last line:
NameError: name 'totl' is not defined. The type is NameError, which means Python met a name it does not know. The message says which name:totl.Find the line number: The line above the last gives the place:
File "stats.py", line 3, in average. Line 3, inside the functionaverage. The next line shows the code itself:return totl / len(numbers).Look at that line: Where does
totlcome from? Line 2 creates a variable calledtotal. The two names differ by one letter, so this is a typo.Trace the call path: The first entry says line 5, in
<module>: the callaverage([2, 4, 6])at the top level started it. That is how the program got to line 3.Fix and rerun: Change
totltototalon line 3. The program prints4.0, sincesumis 12 and12 ÷ 3 = 4.
Newer versions of Python often add a hint under the error, such as a suggestion that you may have meant total. When it appears, read it, but still check that the suggestion makes sense.
Common error types
Error | Usually means | Typical cause |
|---|---|---|
NameError | A name was used that does not exist | Typo, or used before it was defined |
TypeError | An operation got the wrong kind of value | Adding a number to text |
IndexError | A list position is out of range | Asking for item 5 of a 3-item list |
KeyError | A dictionary key is missing | Misspelled or absent key |
SyntaxError | The code is not valid Python | Missing colon or bracket |
ZeroDivisionError | Division by zero | Dividing by a count that is 0 |
Two more messages, decoded quickly
Run items = [1, 2, 3] and then print(items[3]). The last line of the traceback is IndexError: list index out of range. The list has three items at positions 0, 1 and 2, so position 3 does not exist. The fix is to ask for items[2] (the last item) or items[-1], or to check the length first.
Now try print("Total: " + 5). The last line is TypeError: can only concatenate str (not "int") to str. Python will not add text and a number. Turn the number into text with str(5), or use an f-string such as f"Total: {5}". In each case the message names both the problem and the types involved, which is most of what you need.
Searching for help
If the cause is not clear, search for the error type together with the key words of the message, for example python NameError name is not defined. Leave out parts that are specific to your program, such as your variable names or file paths. When you ask someone else for help, give them the full traceback and the few lines of code around the failing line, not just a description.
How to check your answer
Can you say in your own words what the error type means?
Can you point to the exact line and name the thing on it that failed?
After your fix, does the program run, and is the output correct, not just error-free?
If a new error appears, treat it as new information. It means you got past the first one.
Common mistakes
Reading from the top and getting lost in the call path.
Fixing the line above or below the one reported. Look at the reported line first, then at what feeds it.
Ignoring the message and changing code at random.
Assuming the error is always on the reported line. Sometimes the real cause is earlier, such as a variable that was set wrongly.
Pasting only 'it doesn't work' when asking for help.
Where you will use it next
This skill carries over to every language, since all of them report an error type, a message and a place. When the program runs but gives the wrong answer, you will need the full method in debugging a program methodically. To save your working state before trying a fix, use version control with git for beginners.
Frequently asked questions
Do warnings matter?
A warning means the program ran but something looks risky. Read it, because it often points at a future bug.
What if the traceback is very long?
Still start at the bottom. Find the last line that refers to your own file, because that is usually where your fix goes.
