Topic 05

Reading an Error Message

Hands-on

Every programmer sees error messages all day long. The difference between a stuck beginner and everyone else is not that the others make fewer mistakes. It is that they read the message. A Python error report is called a traceback, and it is a precise account of what went wrong and where. It has one rule you need to remember: read it from the bottom up.

Think of the warning light on a car's dashboard. It does not fix the engine, but it names the system that has a problem and saves you guessing. A traceback does the same for your program, and it is far more specific than any dashboard light.

The Last Line First

The last line of a traceback says what kind of problem happened and describes it in a sentence. The kind is a word ending in Error: SyntaxError, NameError, TypeError. Everything above that line is there to tell you where. So start at the bottom, understand the problem, and only then look up.

Then the Location

Above the last line, Python names the file and the line number, and shows the line itself. Under it, a row of carets or tildes marks the exact part that failed. Go to that line in your editor. Most of the time the mistake is right there; sometimes, as the first example shows, the real cause is just before it.

A traceback, read from the bottom up
3. Where: the file and the line number
File "/Users/you/python-course/total.py", line 2
2. The line itself, with a marker under the problem
print(totl) with carets under totl
1. What: the kind of error and a sentence (read this first)
NameError: name 'totl' is not defined. Did you mean: 'total'?

SyntaxError: Python Could Not Read the Line

A SyntaxError means Python could not even understand the text, so nothing in the file ran. Here the opening bracket after print on line 1 is never closed. Python says exactly that, and puts the caret under the bracket that was left open. The line Python struggled with is the next one, but the message points back to where the problem began.

syntax.py
print("Total:", 5
print("done")
Output
  File "/Users/you/python-course/syntax.py", line 1
    print("Total:", 5
         ^
SyntaxError: '(' was never closed

IndentationError: the Blocks Do Not Line Up

An IndentationError means the indentation does not form sensible blocks. In the program below the last line is indented by two spaces, which matches neither the if's block nor the level outside it. The message says the unindent does not match any outer indentation level: Python could not tell which block that line belongs to.

indent.py
temp = 30
if temp > 25:
    print("It is hot today.")
  print("Drink water.")
Output
  File "/Users/you/python-course/indent.py", line 4
    print("Drink water.")
                         ^
IndentationError: unindent does not match any outer indentation level

NameError: a Name That Does Not Exist

A NameError means the program used a name that was never given a value. Most often it is a typo. Python compares the unknown name with the names it does know, and when one is close it suggests it. Here total was typed as totl, and the message asks: did you mean total?

total.py
total = 10
print(totl)
Output
Traceback (most recent call last):
  File "/Users/you/python-course/total.py", line 2, in <module>
    print(totl)
          ^^^^
NameError: name 'totl' is not defined. Did you mean: 'total'?

Notice the first line of this one: Traceback, most recent call last. SyntaxError and IndentationError do not have it, because they stop the file before it starts. A NameError happens while the program is running, and Python reports the path it took to get there. Chapter 8 shows longer paths through several functions; the rule stays the same.

TypeError: the Right Operation on the Wrong Type

A TypeError means an operation was given a type of value it cannot work with. The program below forgot the lesson of Chapter 2: input returns text. Comparing that text with the number 18 fails, and the message says greater-than-or-equal is not supported between a str and an int. The fix is to convert the answer with int first.

adult.py
age = input("Age: ")
if age >= 18:
    print("adult")
A run of adult.py
Age: 20
Traceback (most recent call last):
  File "/Users/you/python-course/adult.py", line 2, in <module>
    if age >= 18:
       ^^^^^^^^^
TypeError: '>=' not supported between instances of 'str' and 'int'

What to Do Next

The method is the same for every error. Read the last line and say in plain words what went wrong. Go to the line number. Look at that line, and at the line above it. Change one thing. Run again. If the message changes, you have made progress, even if there is a new error: it means the old problem is gone and Python got further.

Common Confusions
  • "The top of the traceback is the important part." The last line names the problem. The lines above say where it happened, and matter second.
  • "The error is always on the line shown." Usually it is. Sometimes, as with a bracket left open, the cause starts earlier, and the message points back to it.
  • "Did you mean is just a guess I can ignore." It is usually exactly right. Read it before you start searching.
  • "A new error after a fix means I made things worse." Often it means the first problem is gone and Python got further. Read the new message the same way.
Why It Matters
  • Reading tracebacks turns "it doesn't work" into "line 2 uses a name that doesn't exist", which is the difference between stuck and fixed.
  • Every page from here on shows at least one error. This page is the key to all of them.

Knowledge Check

Which part of a traceback should you read first?

  • The top line, which starts with the word Traceback
  • The middle, where the file's name is shown
  • The last line, which names the error and describes it
  • The row of carets that marks the problem

What does a NameError usually mean?

  • A name was used that was never given a value, often a typo
  • The file was saved with a name that Python dislikes
  • A value had the wrong type for the operation used on it
  • The line could not be read at all because of a bracket

Why does a SyntaxError traceback have no Traceback line at the top?

  • Because Python hides the details of syntax errors
  • Because the error is always on the first line of a file
  • Because syntax errors are only warnings, not real errors
  • Because Python stopped before running anything at all

TypeError: '>=' not supported between instances of 'str' and 'int'. What is the likely fix?

  • Replace the greater-than-or-equal sign with two equals signs
  • Put the number 18 inside quotes so both sides are text
  • Convert the text to a number with int before comparing
  • Move the comparison onto a line of its own above the if

You got correct