Skip to content
← Back to explainers

Python explainer

Read a Python Traceback

About 4 min to read. Allow extra time to work through examples.

Read a traceback from the bottom up, find the line in your own code that caused the error, and spot when a traceback holds more than one error.

This article uses Python. You can make it your practice mode to browse related content across the site.

Save this as average.py and run it:

def average(total: float, count: int) -> float:
    return total / count


print(average(12.0, 0))

Python stops and prints a traceback, its report of where the program failed and which calls led there:

Traceback (most recent call last):
  File "average.py", line 5, in <module>
    print(average(12.0, 0))
          ~~~~~~~^^^^^^^^^
  File "average.py", line 2, in average
    return total / count
           ~~~~~~^~~~~~~
ZeroDivisionError: division by zero

Python 3.15 printed this. Python 3.12 and 3.13 say float division by zero.

Read it from the bottom up

"Most recent call last" means the newest call is at the bottom, next to the error. Start there and work up.

  1. The last line names the exception and gives a message. An exception is the object Python raises when something goes wrong, and ZeroDivisionError is its class.
  2. The entry above it shows the line that raised it, line 2 in average. The marks under the line point at the part that failed, the division.
  3. Each entry higher up is a call that led there. It gives the file, the line number and the function. Python prints the file's full path, which this page shortens. The name <module> means the top level of the file, outside any function. Line 5 called average(12.0, 0) and passed the zero.
  4. Decide what the program should do when count is zero, such as reject the input or skip it. Changing the zero to a one hides the error and returns a wrong average.

Start from your own code

Often the bottom entries are inside a library, with paths into the standard library or site-packages. The bug is usually in what your code passed in. Find the lowest entry in a file you wrote, and check the values it passed.

Check your understanding Your traceback ends inside json/decoder.py with JSONDecodeError: Expecting property name enclosed in double quotes. Where do you look first? Show answer

Move up to the lowest entry in your own code, the line that called json.loads, and look at the text it passed. The json module is rarely the problem. JSON requires double quotes, so text such as {'a': 1} fails with exactly this message.

Check the name Python suggests

Some errors end with a guess:

NameError: name 'totl' is not defined. Did you mean: 'total'?

Python picks a name with almost the same spelling. Check that it is the one you meant, because two variables can have close names and different values.

A SyntaxError means nothing ran

A SyntaxError means Python could not read the file, so none of it ran. You get no list of calls, only the line and a ^ where Python noticed the problem. The message often names the cause, as in '[' was never closed.

When an import fails

Read the module name in the message. If import reporting fails with No module named 'csv_helper', Python found reporting, and one of its own imports failed.

If the missing module is a package you installed, you probably installed it into another Python. Run python -m pip install <name> with the same python command that runs your program. A bare pip can belong to another Python.

A file next to your script with the name of a standard module, such as json.py or random.py, hides the real module. Python 3.13 and later add "consider renaming" to the error. Python 3.12 only says the module has no such attribute.

When a traceback holds more than one error

Later items in this track teach these. For now, learn to spot them.

  • Python can join two tracebacks with "The above exception was the direct cause of the following exception:" or with "During handling of the above exception, another exception occurred:". Either line means one error led to another. The one above is the original failure, and often the one to fix. Keep the Original Error with raise from explains both lines.
  • A traceback drawn with | bars and numbered sections comes from an exception group, one exception that holds several errors. Read each numbered error. Report Several Errors at Once with ExceptionGroup teaches groups.

Lines after the error message are notes, which code adds with add_note():

ValueError: invalid literal for int() with base 10: 'unknown'
reading amount on row 2

So the last line is not always the exception. Look for the line that starts with the class name. Keep the Original Error with raise from shows how to add a note.

Going further

In a terminal, Python 3.13 and later print tracebacks in color. Set PYTHON_COLORS=0 to turn color off, for example when the color codes clutter a log file.

step 1 of 20

Error Handling with Exceptions, Retries and Warnings

Up next Design Exceptions Your Callers Can Catch