Understanding Python Error Messages and How to Fix Them
Here's something nobody tells beginners but absolutely should: error messages are not scary. They're actually trying to help you.
I know. I know. When you see red text and a multi-line message with words like "Traceback" and "Exception," the instinct is to panic. But once you know how to read them, error messages become your most useful debugging tool.
The Anatomy of a Python Error Message
When Python encounters an error, it prints a traceback — a message that tells you:
- Where the error occurred (file name, line number)
- What kind of error it was
- A description of the specific problem
Here's an example. This code:
name = "Alice"
print("Hello " + name + "! You are " + age + " years old.")
Produces this error:
Traceback (most recent call last):
File "example.py", line 2, in <module>
print("Hello " + name + "! You are " + age + " years old.")
^^^
NameError: name 'age' is not defined
Read it from the bottom up — that's almost always the most useful direction:
NameError: name 'age' is not defined— the type of error and the specific problem. We usedagewithout ever defining it.File "example.py", line 2— the error happened on line 2 ofexample.py- The
^^^carets point directly at the part of the line that caused the problem
Python 3.10+ has especially helpful carets that point exactly where things went sideways. Earlier versions are slightly less precise but still tell you plenty.
The Most Common Error Types
SyntaxError — You wrote something Python can't parse. Usually means you forgot a colon, parenthesis, or quote, or mistyped a keyword.
if x > 5 # SyntaxError: expected ':'
print("hello")
print("hello" # SyntaxError: EOF while scanning (missing closing parenthesis)
NameError — You used a variable or function name that doesn't exist (usually a typo or using a variable before defining it).
prnt("hello") # NameError: name 'prnt' is not defined
TypeError — You tried to do something with the wrong type. Like adding a string and an integer.
age = 25
print("Age: " + age) # TypeError: can only concatenate str (not "int") to str
IndexError — You tried to access a list index that doesn't exist.
fruits = ["apple", "banana"]
print(fruits[5]) # IndexError: list index out of range
KeyError — You tried to access a dictionary key that doesn't exist.
d = {"a": 1}
print(d["b"]) # KeyError: 'b'
ValueError — You passed the right type but an invalid value. Like trying to convert "banana" to an integer.
number = int("banana") # ValueError: invalid literal for int()
ZeroDivisionError — You tried to divide by zero. (Genuinely undefined in mathematics too, for what it's worth.)
result = 10 / 0 # ZeroDivisionError: division by zero
How to Debug: A Strategy
When your code doesn't work, here's a systematic approach that will save your sanity:
Step 1: Read the error message bottom-up. The bottom line tells you what went wrong. The lines above it tell you where.
Step 2: Go to the line number mentioned. That's where the problem is (or very close to it).
Step 3: Add print statements. When you genuinely don't understand what's happening, print out the values of variables at various points to see what Python "sees."
# I'm confused about why this doesn't work
def calculate_percentage(part, whole):
print(f"DEBUG: part={part}, whole={whole}") # Temporary debug line
result = part / whole * 100
print(f"DEBUG: result={result}") # Temporary debug line
return result
Step 4: Isolate the problem. Comment out parts of your code until you find the minimum code that still shows the error.
Step 5: Search the error message. Copy the error message (just the last line is usually enough) and search for it online. You are not the first person to see that error. Stack Overflow will have an answer.
Step 6: Ask AI. Paste your code and the error message into ChatGPT or another AI assistant and ask it to explain the error. This is now one of the most effective debugging tools available, and there's zero shame in using it.
Handling Errors Gracefully: try and except
Instead of letting errors crash your program, you can catch them with try/except:
try:
age_input = input("Enter your age: ")
age = int(age_input) # This might raise a ValueError
print(f"In 10 years, you'll be {age + 10}")
except ValueError:
print("That doesn't look like a valid age!")
print("Please enter a whole number.")
The try block runs. If an error occurs, Python jumps to the except block instead of crashing. If no error occurs, the except block is skipped entirely.
Here's a more robust version of our input loop from earlier:
while True:
try:
age = int(input("Enter your age: "))
if age < 0 or age > 150:
print("That's not a realistic age. Try again.")
else:
break # Valid age, exit the loop
except ValueError:
print("Please enter a number, not text.")
print(f"Your age is {age}. Great!")
This kind of input validation is what separates programs that hold together from ones that fall apart the moment a user does something unexpected.
Only visible to you
Sign in to take notes.