Python Basics for Vibe Coders, Part 8: Read Error Messages from the Bottom Up
Read Python error messages (tracebacks) from the last line up: 6 common errors, friendlier 3.15 messages, try/except, and how to report errors to AI.
When you vibe code, you see red error messages all the time. It's tempting to skip reading them and paste the whole thing into the AI. That works, but if you can read just the last line, you'll find the cause much faster and ask the AI a sharper question. This is Part 8 of the 10-part series "Python Basics for Vibe Coders," and it covers how to read error messages (tracebacks) and how to handle errors you can see coming with try / except. The examples are written for Python 3.15, and I ran them in Python 3.14.2 to check the results (I checked the messages that changed in 3.15 against the official docs).
Key Takeaways
- An error isn't your program breaking. It's a clue from Python.
- Read a traceback from the bottom line up. The last line tells you the type of error and the reason.
- The
File "...", line Nlines above it tell you the file and line number where the error happened.- Use
try / except ErrorName:only for errors you can predict. If you hide every error with a bareexcept:, you'll never find the real cause.
An error is your GPS saying "Road closed"
When your GPS tells you a road is closed, you can find another route. Error messages work the same way. Because they tell you what went wrong, you can fix it.
They're a bit like the red marks on a graded test, but friendlier. They don't just mark what's wrong; they tell you which line it happened on and what happened there.
How to read a Python error message (traceback)
If you try to turn text that isn't a number into an integer, you get an error. For example, if line 3 of a file called app.py contains int("three"), you'll see this message (the file path depends on your setup):
Traceback (most recent call last):
File "app.py", line 3, in <module>
number = int("three")
ValueError: invalid literal for int() with base 10: 'three'
(For some errors, Python adds a row of ~ and ^ marks under the code to point at the part that failed. This example doesn't get them.)
| Where | What it says | How to read it |
|---|---|---|
| Top line | Traceback (most recent call last): | Just a heading that says "an error happened" |
| Middle | File "app.py", line 3 | Which file and which line |
| Below that | number = int("three") | The code that caused the problem |
| Last line | ValueError: ... | Error type: reason. Start reading here |
The last line means "int() got the text 'three', which it can't convert." When an error happens inside a function, several File ... line ... lines stack up in the middle. The lower a line is, the closer it is to where the error actually happened.
Here are the error types you'll see most often, matched with the parts of this series where they come up.
| Error | Common cause | Related part |
|---|---|---|
SyntaxError | Invalid syntax (a missing parenthesis, quote, or colon; mixing up = and ==) | Parts 1 and 3 |
NameError | A name you never created, or a typo (Print) | Part 1 |
TypeError | Calculating with values of different types ("20" + 1) | Part 2 |
ValueError | The type is right but the value isn't (int("three")) | This part |
IndexError | A position that doesn't exist in the list | Part 5 |
KeyError | A key that doesn't exist in the dictionary | Part 6 |
Friendlier messages in Python 3.15
Python 3.15 adds more messages that suggest the right name when you call something that doesn't exist. In the example from the official docs, using push on a list ends like this (the start of the traceback is omitted; see What's New in Python 3.15):
>>> [1, 2, 3].push(4)
AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'?
When you see "Did you mean ...?", check that suggestion first. Python picked a candidate with a similar name, so it isn't always the right answer. push is the name used for JavaScript arrays, so you may see this message in code where habits from another language have crept in.
try / except: handling errors you can predict
Some errors you can see coming, like a user typing letters instead of a number. You can handle those ahead of time.
def to_number(text):
try:
return int(text)
except ValueError:
return None
print(to_number("42"))
print(to_number("three"))
42
None
If a ValueError happens while the code inside try is running, Python stops at that line and jumps straight to the code under except ValueError:. Any try code after the line that failed is skipped.
Common trap: is it safe to swallow every error with except:?
try:
...
except:
pass
If you write except: with no error name and put pass (do nothing) under it, the program won't stop. That looks safe, but it also silently hides things like a NameError caused by a typo. The results are wrong, there's no error message at all, and you have no way to find the cause.
If you see except: or except Exception: pass in AI code, ask: "Which error were you expecting here? Change it to handle only that error." The rule is to name the error you're handling, like ValueError.
How to pass an error to the AI
- Paste the entire error message. If you only give it the last line, the AI can't tell which line the error came from.
- Read the last line first and add one line about what you think the cause is. For example: "I get a
ValueErrorfromint("three"). I think the user typed letters." - Say what you were trying to do and what command you used to run it.
- Remove any API keys, passwords, or personal folder paths from the error message before you send it.
Check yourself
- Where should you look first in a traceback? → The error type and reason on the very last line. The top line is just a heading.
- If an error that
excepthandles happens on the third line insidetry, what happens? → Python stops at that line and goes straight toexcept. The program only ends right away when the error isn't handled.
Try it yourself
Write to_int(text, default=0), which takes a string and converts it to an integer, but gives back the default value 0 if that fails. If to_int("7") gives 7 and to_int("abc") gives 0, you've got it. If you get stuck, check the spelling of the error name after except and your indentation.
def to_int(text, default=0):
try:
return int(text)
except ValueError:
return default
print(to_int("7"))
print(to_int("abc"))
7
0
Previous and next
- Previous: Part 7: Functions, and Why print Is Not return
- Next: Part 9: Saving Files and encoding="utf-8" covers saving files that stay around after your program ends, and
encoding="utf-8", which keeps non-English text from coming out garbled.
The full series list is at the end of Part 10.