PyDebug guides · 6 November 2026
Read a Python Traceback: A Practical Guide
A traceback is a record of how Python reached an exception. It is not a list of unrelated errors. Read it as a path from the original call to the place where execution stopped, then use the exception type and message to form a hypothesis you can test.
Start with the last line
Traceback (most recent call last):
File "app.py", line 5, in <module>
print(average([]))
File "app.py", line 3, in average
return sum(values) / len(values)
ZeroDivisionError: division by zero
The final line says what happened: a division by zero. The frame immediately above it points to the expression that failed. The earlier frame tells you who called that function and with what expression. Actual line numbers and paths depend on your file.
Trace the values, not just the line
At the failing line, values is an empty list. Therefore len(values) is zero. The bug is not fixed by changing the error message or blindly wrapping the entire program in except Exception; decide what an empty input should mean for your application.
def average(values):
if not values:
raise ValueError("average needs at least one value")
return sum(values) / len(values)
Now the failure occurs at a deliberate boundary with a clearer explanation. Another application might choose to return None instead; callers must then handle that choice. Test a normal input, a one-element list and an empty list to confirm the contract.
Separate the exception from its cause
settings = {"retries": 0}
print(settings["timeout"]) # KeyError: 'timeout'
The missing key might be a typo, absent configuration or unexpected input. If a timeout is optional, use an explicit default: settings.get("timeout", 30). If it is required, validate the configuration and report the missing field rather than silently choosing a default. Importantly, get returns an existing value even if that value is None; the default is used only when the key is absent.
Reduce the failing example
- Keep the exact input that reproduces the failure, removing unrelated code and private information.
- Find the last frame in your own code and write down the values and types used there.
- Make one hypothesis: for example, “this field is text, not an integer.” Check it with
repr(value)andtype(value). - Apply the smallest correction and rerun the failing case, a normal case and a boundary case.
- Turn the original failure into a regression test so it cannot quietly return.
Chained exceptions and syntax errors
Python can show one exception followed by “The above exception was the direct cause” or “During handling of the above exception”. Read both: the first can reveal the original failure; the last shows what ultimately escaped. In a SyntaxError, Python could not parse the program at all. The arrow marks where the parser noticed the problem, which may be after the actual missing bracket or quote.
Example regression tests
assert average([2, 4]) == 3
try:
average([])
except ValueError:
pass
else:
raise AssertionError("empty input must raise ValueError")
Explore the Python error reference for specific messages, or practise isolating failures in the playground. For a broader workflow, see the Python debugging guide.