Every Python beginner runs into the same handful of errors repeatedly. This guide covers the most common ones, what they actually mean, and how to fix each one quickly.
If you’ve worked through our guides on if statements and file handling, you’ve probably already seen a few of these errors firsthand. This guide names them explicitly and pairs each with its typical fix.
Two Categories: Syntax Errors and Exceptions
According to Python’s official documentation, syntax errors (also called parsing errors) are the most common complaint for beginners — Python detects them before your code even runs, pointing an arrow at roughly where the problem was found. Exceptions, by contrast, are errors that occur during execution, even when the code is syntactically valid.
while True print('Hello world')
# SyntaxError: invalid syntax (missing colon)NameError
Occurs when you reference a variable that doesn’t exist — usually a typo, or using a variable before it’s been assigned:
print(age)
# NameError: name 'age' is not definedFix: Check the spelling matches exactly, and confirm the variable was actually assigned before this line runs.
TypeError
Occurs when an operation is applied to an incompatible type — like adding a string and a number directly:
print("Age: " + 25)
# TypeError: can only concatenate str (not "int") to strFix: Convert one side explicitly — str(25) in this case.
IndexError
Occurs when you try to access a list index that doesn’t exist:
fruits = ["apple", "banana"]
print(fruits[5])
# IndexError: list index out of rangeFix: Double-check the list’s actual length, and remember indexing starts at 0.
KeyError
Occurs when you try to access a dictionary key that doesn’t exist:
person = {"name": "Alex"}
print(person["age"])
# KeyError: 'age'Fix: Use .get("age") instead, which returns None rather than raising an error if the key is missing.
IndentationError
Python uses indentation to define code blocks, so inconsistent spacing raises an error directly:
if True:
print("hello")
# IndentationError: expected an indented blockFix: Make sure every line inside a block uses consistent indentation — most editors handle this automatically once configured correctly.
FileNotFoundError
Covered in more depth in our file handling guide — occurs when trying to open a file that doesn’t exist at the given path.
Fix: Double-check the filename and path, and confirm the file actually exists in that location relative to your script.
AttributeError
Occurs when you try to use a method or property that doesn’t exist on a given object — often from confusing which type you’re actually working with:
name = "Alex"
name.append("!")
# AttributeError: 'str' object has no attribute 'append'According to DataCamp’s guide to exception handling in Python, an AttributeError is raised when attribute assignment or reference fails — in this example, append() is a list method, not a string method, which is exactly the kind of type confusion this error signals.
Fix: Use type(variable) to confirm what type you’re actually dealing with, then check that type’s actual available methods.
ZeroDivisionError
Occurs when dividing by zero, which Python — like math generally — doesn’t allow:
result = 10 / 0
# ZeroDivisionError: division by zeroFix: Check the divisor isn’t zero before dividing, especially when it comes from user input or a calculation that could legitimately produce zero.
ValueError
Occurs when a function receives an argument of the right type but an inappropriate value — a common example is trying to convert text that isn’t a valid number:
age = int("twenty-five")
# ValueError: invalid literal for int() with base 10: 'twenty-five'Fix: Validate input before converting it, or wrap the conversion in a try/except block to handle unexpected input gracefully rather than crashing.
ModuleNotFoundError
Occurs when importing a library that isn’t installed, or misspelling its name:
import request
# ModuleNotFoundError: No module named 'request'Fix: Double-check the spelling (the popular library is actually named “requests,” plural), and confirm it’s installed with your package manager if the name is correct.
Reading an Error Message, Step by Step
According to freeCodeCamp’s guide to common Python errors, reading the error message carefully to determine the exact location of the problem is the single most useful debugging habit for a beginner. Python’s traceback shows the file, line number, and the specific error type — always read from the bottom up, since the last line names the actual error, while the lines above trace how execution got there.
Using try/except Effectively
Once you can recognize a specific error, wrapping the risky code in a try/except block lets your program handle it gracefully instead of crashing entirely:
try:
age = int(input("Enter your age: "))
except ValueError:
print("Please enter a valid number.")Catching the specific exception type (ValueError here) rather than a bare except: is worth building as a habit — a bare except catches everything, including errors you didn’t anticipate and genuinely want to know about, which can hide real bugs behind a generic “something went wrong” message that gives you no useful information.
Common Questions
Why does my code work sometimes and fail other times with the same input? This usually points to a bug that depends on some external state (like file existence or user input) rather than the code itself changing — worth checking what’s different between the working and failing runs.
Should I use try/except for every possible error? No — wrapping absolutely everything in try/except can hide genuine bugs you’d want to know about. Use it selectively, for situations you specifically anticipate (like a missing file or invalid user input), not as a blanket catch-all around your entire program.
Why does my traceback mention files I didn’t write? If your code calls a library function, and that function raises an error, the traceback shows the full chain of calls — including code inside the library itself. Focus on the parts of the traceback that reference your own file first, since that’s usually where the actual fix belongs.
A Practical Example: Debugging a Real Traceback
Here’s a realistic traceback you might see, and how to read it step by step:
Traceback (most recent call last):
File "main.py", line 7, in <module>
total = calculate_total(items)
File "main.py", line 3, in calculate_total
return sum(item.price for item in items)
AttributeError: 'dict' object has no attribute 'price'Reading from the bottom up: the actual error is an AttributeError, caused because something is a dictionary rather than an object with a .price attribute. Moving up, this happened inside calculate_total on line 3, which was called from line 7 in the main script. This tells you exactly where to look — either items contains dictionaries instead of objects, or the function was written assuming the wrong data structure. Tracebacks look intimidating at first, but they’re genuinely a map pointing directly at the problem, once you know to read them from the bottom.
When an Error Message Doesn’t Make Sense
Occasionally an error message references something confusing, or points to a line that looks completely fine at first glance. In these cases, it helps to check the line immediately above the flagged one — a missing closing bracket or quote on an earlier line often causes Python to report the error on a later, unrelated-looking line, since that’s where the parser finally notices something is structurally wrong. Adding print statements before the failing line, to check the actual values of your variables at that point, is also a reliable way to narrow down what’s really happening when the error message alone isn’t enough.
Quick-Reference Guide
- SyntaxError — invalid code structure, caught before running.
- NameError — referencing an undefined variable.
- TypeError — incompatible types in an operation.
- IndexError / KeyError — accessing a missing list index or dictionary key.
- IndentationError — inconsistent code block indentation.
- Read tracebacks bottom-up — the last line names the actual error.
Conclusion
These handful of errors account for the overwhelming majority of what beginners run into — recognizing each one by name, rather than treating every red traceback as an unfamiliar mystery, turns debugging from frustrating into routine.
In the next guide in this series, we’ll cover Python dictionaries — the data structure behind several of the errors and examples covered throughout this series.
Explore More Python for Beginners Guides →

When not writing, Alex is probably debugging someone else’s code.