Types of Errors in Python (With Real Examples)

There are three main types of errors in Python: syntax errors, which stop the code from running at all; runtime errors (exceptions), which crash it partway through; and logical errors, which run fine but give the wrong answer.

if price > 10        # SyntaxError: expected ':'
100 / 0              # ZeroDivisionError at runtime
total = price * 0.15 # logical error: that's the discount, not the price

All the error messages below are copied from Python 3.12.5 running in a Windows Command Prompt, so they’ll match what you see.

I’ll go through each type with real tracebacks, list the built-in exceptions you’ll meet most, show how to read a traceback, and how to handle errors with try and except.

1. Syntax errors in Python

A syntax error means Python can’t understand the code, so nothing runs, not even the lines above the mistake. Missing colons, unclosed brackets and stray quotes are the usual causes:

price = 19.99
if price > 10
    print("Free shipping")

Output:

  File "C:\pyguides\syntax_error.py", line 2
    if price > 10
                 ^
SyntaxError: expected ':'
Command Prompt output of a Python SyntaxError expected colon after an if statement, with a caret pointing at the problem
Python points a caret at the spot and says exactly what it expected: a colon.

Recent versions of Python give much friendlier messages than older ones. Read the last line first; it usually tells you the fix.

IndentationError: a special kind of syntax error

Python uses indentation to group code, so a missing or uneven indent is a syntax problem too. IndentationError is a subclass of SyntaxError:

total = 120.00
if total > 100:
print("You get a 10% discount")

Output:

  File "C:\pyguides\indent_error.py", line 3
    print("You get a 10% discount")
    ^
IndentationError: expected an indented block after 'if' statement on line 2

Set your editor to insert four spaces when you press Tab and this one mostly disappears. Mixing tabs and spaces gives a related TabError.

2. Runtime errors (exceptions) in Python

Runtime errors happen while the program runs, when an operation can’t be done. Python raises an exception, and if nothing catches it, the program stops. These are the ones you’ll see most:

checks = [
    ("NameError",         lambda: print(totl)),
    ("TypeError",         lambda: "Total: " + 42),
    ("ValueError",        lambda: int("12.50")),
    ("ZeroDivisionError", lambda: 100 / 0),
    ("IndexError",        lambda: ["TX", "CA"][5]),
    ("KeyError",          lambda: {"TX": 0.0625}["NY"]),
    ("AttributeError",    lambda: (3.5).append(1)),
    ("FileNotFoundError", lambda: open("sales_2026.csv")),
    ("ModuleNotFoundError", lambda: __import__("pandaz")),
]
for expected, fn in checks:
    try:
        fn()
    except Exception as err:
        print(f"{type(err).__name__:<20} {err}")

Output:

NameError            name 'totl' is not defined
TypeError            can only concatenate str (not "int") to str
ValueError           invalid literal for int() with base 10: '12.50'
ZeroDivisionError    division by zero
IndexError           list index out of range
KeyError             'NY'
AttributeError       'float' object has no attribute 'append'
FileNotFoundError    [Errno 2] No such file or directory: 'sales_2026.csv'
ModuleNotFoundError  No module named 'pandaz'
Command Prompt output listing common Python runtime errors: NameError, TypeError, ValueError, ZeroDivisionError, IndexError, KeyError and more
Each exception’s name tells you the category, and the message tells you the detail.
ExceptionTypical causeQuick fix
NameErrorTypo, or variable used before it’s definedCheck the spelling and order
TypeErrorMixing types, like str + intConvert with str() or int()
ValueErrorRight type, bad value, like int("12.50")Validate input first
ZeroDivisionErrorDividing by zeroCheck the divisor
IndexErrorList index past the endCheck len()
KeyErrorMissing dictionary keyUse dict.get() or in
AttributeErrorMethod the object doesn’t haveCheck the type
FileNotFoundErrorWrong path or nameCheck the working directory
ModuleNotFoundErrorPackage not installed or typopython -m pip install

Some have their own guides: fixing IndexError: list index out of range, dictionary KeyError and UnboundLocalError.

How do you read a Python traceback?

A traceback lists the calls that led to the error, oldest first. Start at the bottom for the error itself, then work up to find the line in your code that caused it:

def average(prices):
    return sum(prices) / len(prices)

def report(store, prices):
    print(f"{store}: ${average(prices):.2f} average sale")

report("Austin", [12.50, 30.00, 7.25])
report("Denver", [])

Output:

Austin: $16.58 average sale
Traceback (most recent call last):
  File "C:\pyguides\traceback_demo.py", line 8, in <module>
    report("Denver", [])
  File "C:\pyguides\traceback_demo.py", line 5, in report
    print(f"{store}: ${average(prices):.2f} average sale")
                       ^^^^^^^^^^^^^^^
  File "C:\pyguides\traceback_demo.py", line 2, in average
    return sum(prices) / len(prices)
           ~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero
Command Prompt output of a Python traceback ending in ZeroDivisionError when averaging an empty list of prices
The Austin line worked. Denver passed an empty list, so len(prices) was 0 inside average().

The crash is in average(), but the real bug is calling it with an empty list. Tracebacks show where it broke, and you decide where to fix it.

3. Logical errors in Python

Logical errors are the sneakiest type because Python doesn’t complain. The code runs and prints a result; it’s just wrong. Only testing and checking output catches them:

prices = [10.00, 20.00, 30.00]

total = 0
for i in range(1, len(prices)):      # bug: skips the first item
    total += prices[i]
print(f"buggy total: ${total:.2f}")   # no error, just the wrong answer

assert sum(prices) == 60.00, "total is off"
print(f"fixed total: ${sum(prices):.2f}")

discount = 0.15
price = 80.00
print(f"buggy sale price: ${price * discount:.2f}")       # the discount, not the price
print(f"fixed sale price: ${price * (1 - discount):.2f}")

Output:

buggy total: $50.00
fixed total: $60.00
buggy sale price: $12.00
fixed sale price: $68.00
Command Prompt output of Python logical errors: a loop that skips the first price and a discount calculated instead of the sale price
No traceback anywhere, yet both buggy lines print wrong dollar amounts.

I catch most of mine with small checks like assert, print statements while developing, and tests with numbers I can work out by hand.

Handling errors with try and except

You can catch runtime errors and respond instead of crashing. Catch specific exceptions, and raise your own when your program’s rules are broken:

class OutOfStockError(Exception):
    pass

stock = {"mug": 3, "hoodie": 0}

def buy(item, qty):
    if item not in stock:
        raise KeyError(f"unknown item {item!r}")
    if stock[item] < qty:
        raise OutOfStockError(f"only {stock[item]} {item}(s) left")
    stock[item] -= qty
    return f"bought {qty} {item}(s)"

for item, qty in [("mug", 2), ("hoodie", 1), ("hat", 1), ("mug", "two")]:
    try:
        print(buy(item, qty))
    except OutOfStockError as err:
        print("Sorry:", err)
    except (KeyError, TypeError) as err:
        print(f"{type(err).__name__}: {err}")

Output:

bought 2 mug(s)
Sorry: only 0 hoodie(s) left
KeyError: "unknown item 'hat'"
TypeError: '<' not supported between instances of 'int' and 'str'

Never write a bare except: that hides every error, including your typos. More patterns in catching multiple exceptions in Python and exception handling in Python.

The Python exception hierarchy

Exceptions are classes, arranged in a family tree. Catching a parent class catches all of its children, which is why except OSError also catches FileNotFoundError:

for exc in (ZeroDivisionError, KeyError, FileNotFoundError, ModuleNotFoundError, IndentationError):
    chain = " -> ".join(c.__name__ for c in exc.__mro__[:-1])
    print(chain)

Output:

ZeroDivisionError -> ArithmeticError -> Exception -> BaseException
KeyError -> LookupError -> Exception -> BaseException
FileNotFoundError -> OSError -> Exception -> BaseException
ModuleNotFoundError -> ImportError -> Exception -> BaseException
IndentationError -> SyntaxError -> Exception -> BaseException

Syntax errors aren’t something you can usually catch in the same file, since the file never starts running. Runtime and logical errors are where your handling and testing effort goes.

Keep these handy for the next error you run into:

Frequently asked questions

What are the 3 types of errors in Python?

Syntax errors (the code can’t be parsed), runtime errors or exceptions (something fails while running), and logical errors (the code runs but gives wrong results).

What’s the difference between an error and an exception?

In everyday use they overlap. Technically, exceptions are the runtime errors Python raises as objects, which you can catch with try/except.

Which Python errors are most common?

SyntaxError, IndentationError, NameError, TypeError, ValueError, IndexError and KeyError cover most beginner problems.

How do I find a logical error?

Test with inputs where you know the answer, print intermediate values, add assert checks, or step through with a debugger.

Can I create my own exception type?

Yes. Subclass Exception, like class OutOfStockError(Exception): pass, then raise it.

Where is the full list of built-in exceptions?

See the built-in exceptions page in the Python docs, which includes the full hierarchy.