Reading a traceback
finding the guilty line in thirty seconds
What it is
A traceback is what Python prints when a program crashes. It looks intimidating, reads in half a minute, and almost always names the guilty line outright.
The skill pays twice: you understand immediately what happened, and you can hand the AI not "it doesn't work" but the exact cause. The second matters more — it decides whether it gets fixed on the first try or the fifth.
What it looks like in code
Here is a program that requests the weather and shows the temperature:
import json
def fetch_weather(city: str) -> dict:
# The server's reply when the city is not found
raw = '{"cod": "404", "message": "city not found"}'
return json.loads(raw)
def format_report(data: dict) -> str:
temp = data["main"]["temp"]
return f"It is {temp} degrees right now"
def handle_command(city: str) -> str:
data = fetch_weather(city)
return format_report(data)
if __name__ == "__main__":
print(handle_command("Tonsberg"))Run it, and you get:
Traceback (most recent call last):
File "/tmp/tbdemo2/weather2.py", line 21, in <module>
print(handle_command("Tonsberg"))
~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/tmp/tbdemo2/weather2.py", line 17, in handle_command
return format_report(data)
File "/tmp/tbdemo2/weather2.py", line 11, in format_report
temp = data["main"]["temp"]
~~~~^^^^^^^^
KeyError: 'main'How to read it
Rule one: read bottom to top. The last line is the point; everything else is how we got here.
KeyError: 'main'KeyError means: something reached for a dictionary key that isn't there. The
key is named outright — 'main'.
Rule two: the second-to-last block is the crash site.
File "/tmp/tbdemo2/weather2.py", line 11, in format_report
temp = data["main"]["temp"]
~~~~^^^^^^^^File, line 11, function format_report. The marks under the line are
Python's own hint (since 3.11): the ^^^^ points at exactly the part of the
expression that failed. Here you can see the problem is ["main"], not
["temp"]. That matters: without the marks you would be guessing which of the
two lookups was to blame.
Rule three: the blocks top to bottom are the call path. The program
started at line 21, went into handle_command (line 17), from there into
format_report (line 11), and crashed. That path answers the question "where
did the data come from" — and that is almost always the real cause.
Rule four: look for your own files. In a real traceback half the lines
come from libraries: site-packages, aiogram, asyncio. You can scroll
past them. Look at the last line that mentions your file: the error is
almost always there, even when the crash happened inside a library.
What we learned
Line 11 is not at fault — it honestly does what it was asked. Line 6 is at fault: the server replied "city not found" and the code decided it had received the weather. The crash site and the cause are different places. The traceback shows the first; the call path helps you find the second.
What to tell the AI
The most common mistake is retelling the error in your own words.
doesn't work, throws some key errorThe AI has to guess: which key, in which file, on which line. It will start rewriting everything in sight.
The right way is to hand over the whole traceback, adding what it does not contain: what you did and what you expected.
Crashes when requesting the weather for a city that doesn't
exist. Expected the reply "City not found", got an exception.
Traceback (most recent call last):
File "weather.py", line 21, in <module>
print(handle_command("Tonsberg"))
File "weather.py", line 17, in handle_command
return format_report(data)
File "weather.py", line 11, in format_report
temp = data["main"]["temp"]
~~~~^^^^^^^^
KeyError: 'main'
Fix it so that the server error is handled in fetch_weather,
rather than surfacing in format_report.That last sentence matters. Without it the AI will most likely wrap line 11 in
a try/except or substitute data.get("main", {}). It stops crashing, the
user gets "It is None degrees right now", and the real error goes into hiding.
What to look for
The AI muffles the error instead of handling it. The signs in generated
code: except Exception: pass, except: return None, .get(key, {}) instead
of a check. The code stops crashing and starts lying.
The AI fixes the crash site, not the cause. If it only changed the line the traceback pointed at, ask: "where did the wrong data reach this function from?"
A truncated traceback. Copy only the last line and the AI never sees the
call path, so it fixes blind. Copy the whole thing, starting at the word
Traceback.
An asynchronous traceback is longer and messier: it holds asyncio frames
and library internals. Same rule — find the last line with your own file in
it.
Cheat sheet
Read bottom to top: the last line says what happened.
The second-to-last block is the file and line of the crash;
^^^^marks the guilty part of the expression.Scroll past other people's files, find the last one of yours.
Crash site ≠ cause. Look for the cause further up the call path.
Give the AI the whole traceback plus what you did and what you expected.