Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Python Module 1 – Getting started: install, run and read Python

Read error messages and tracebacks calmly

Read a Python traceback from the bottom up, recognise the errors beginners meet most often, and use the clearer messages of Python 3.14 to fix the failing line.

  • Beginner
  • 20 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot

What you will learn

  • Read a traceback from the bottom up to find the failing line
  • Recognise the most common beginner exceptions and their usual causes
  • Use help(), the documentation and minimal examples to get unstuck

Before you start

On this page

When a program fails, Python stops and prints a traceback. The first few look alarming, but a traceback is a precise report with three parts: what went wrong, the line where it happened, and the chain of calls that led there. Reading one in that order, from the bottom up, is the quickest way to find most bugs.

Read it from the bottom up

This program adds up two bills. The first one works; the second has a typo in its order:

A traceback through three functions Python · bill.py
prices = {"tea": 30, "toast": 45, "coffee": 60}


def line_total(item, quantity):
    return prices[item] * quantity


def bill(order):
    total = 0
    for item, quantity in order:
        total += line_total(item, quantity)
    return total


print("First bill:", bill([("tea", 2), ("toast", 1)]))
print("Second bill:", bill([("tea", 1), ("cofee", 2)]))

Output (exit status 1)

First bill: 105

Printed as an error (standard error)

Traceback (most recent call last):
  File "bill.py", line 16, in <module>
    print("Second bill:", bill([("tea", 1), ("cofee", 2)]))
                          ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "bill.py", line 11, in bill
    total += line_total(item, quantity)
             ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "bill.py", line 5, in line_total
    return prices[item] * quantity
           ~~~~~~^^^^^^
KeyError: 'cofee'

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 bill.py

Start at the last line and work upwards:

  1. The last line names the exception and gives its message. KeyError: 'cofee' says that a dictionary was asked for a key it does not have, and the message is that key.
  2. The frame just above it shows where it happened: File "bill.py", line 5, in line_total, then the line itself. The ~ and ^ marks under it pick out the part of the line that failed, the lookup prices[item].
  3. Each frame higher up is a call that led there. bill() called line_total() on line 11, and the file’s top level (<module>) called bill() on line 16. “Most recent call last” means the frames run from the first call down to the line that failed.

The line that failed is not always the line to fix. Nothing is wrong with line_total(): it was given a bad value. Keep reading upwards until you reach the line where the bad value came from, here the order on line 16. Notice too that the first bill was printed: everything before the failing line ran normally.

When the failing frames are not your code

If you pass something wrong to a function of the standard library or of a package, the last frames are inside that function’s own files:

A traceback that ends in the standard library Python · bad_json.py
import json

settings_text = "{'theme': 'dark'}"
settings = json.loads(settings_text)
print("Theme:", settings["theme"])

Output (exit status 1)

Printed as an error (standard error)

Traceback (most recent call last):
  File "bad_json.py", line 4, in <module>
    settings = json.loads(settings_text)
  File "…/lib/python3.14/json/__init__.py", line 352, in loads
    return _default_decoder.decode(s)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "…/lib/python3.14/json/decoder.py", line 345, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "…/lib/python3.14/json/decoder.py", line 361, in raw_decode
    obj, end = self.scan_once(s, idx)
               ~~~~~~~~~~~~~~^^^^^^^^
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 bad_json.py

The frames under …/lib/python3.14/json/ belong to Python’s json module (the … stands for the folder Python is installed in, which differs from one computer to the next). Do not go looking for a bug there. Find the last frame that is in your own file, line 4, where json.loads() was called, and check what you gave it. The message says the rest: JSON needs double quotes around names, so the text should have been '{"theme": "dark"}'.

JSON Validator Paste a JSON text to see the exact line and column where it stops being valid JSON.

A SyntaxError means nothing ran

Python reads a whole file before running any of it. When the grammar is wrong, it reports a SyntaxError and runs nothing at all, not even the lines above the mistake:

A misspelt keyword Python · typo_keyword.py
print("This line never runs")


def greeting(name):
    retrun "Hello, " + name


print(greeting("Asha"))

Output (exit status 1)

Printed as an error (standard error)

  File "typo_keyword.py", line 5
    retrun "Hello, " + name
    ^^^^^^
SyntaxError: invalid syntax. Did you mean 'return'?

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 typo_keyword.py

There is no “Traceback (most recent call last)” line this time, because no call happened: the file never started. The first line, a print(), printed nothing for the same reason.

Version note

New in Python 3.14: when a word looks like a misspelt keyword, the message suggests the keyword, as in Did you mean 'return'? above. Python 3.13 and older say only invalid syntax.

Sometimes the line Python shows looks perfectly fine. The cause is then usually earlier, often a bracket or a quote that was opened and never closed. Python points at where it was opened:

A bracket that was never closed Python · unclosed.py
marks = [72, 88, 95
print(sum(marks) / len(marks))

Output (exit status 1)

Printed as an error (standard error)

  File "unclosed.py", line 1
    marks = [72, 88, 95
            ^
SyntaxError: '[' was never closed

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 unclosed.py

The list on line 1 never gets its ]. Inside brackets Python keeps reading on the following lines, so it reaches the end of the file still inside the list, and reports the line where the list began. IndentationError, for lines indented in a way that does not match the blocks around them, is a kind of SyntaxError too and is reported the same way, before anything runs.

The errors you will meet most

Each of these eight lines makes a different mistake. The program runs them one at a time and prints the last line of each traceback, so you can see the exact messages of this version of Python:

Eight common mistakes and their messages Python · error_gallery.py
import traceback

# Eight one-line mistakes. exec() runs each line as a tiny program and the error is caught,
# so you see the last line of every traceback, exactly as Python prints it.
mistakes = [
    "print(scroe)",
    '"3" + 4',
    'int("three")',
    "[10, 20, 30][3]",
    '{"tea": 30}["coffee"]',
    '"text".uper()',
    "1 / 0",
    "import numpyy",
]
for code in mistakes:
    try:
        exec(code)
    except Exception as error:
        last_line = traceback.format_exception_only(error)[-1].strip()
        print(f"{code:<24}{last_line}")

Output

print(scroe)            NameError: name 'scroe' is not defined
"3" + 4                 TypeError: can only concatenate str (not "int") to str
int("three")            ValueError: invalid literal for int() with base 10: 'three'
[10, 20, 30][3]         IndexError: list index out of range
{"tea": 30}["coffee"]   KeyError: 'coffee'
"text".uper()           AttributeError: 'str' object has no attribute 'uper'. Did you mean: 'upper'?
1 / 0                   ZeroDivisionError: division by zero
import numpyy           ModuleNotFoundError: No module named 'numpyy'

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 error_gallery.py

When a name or an attribute is misspelt and something close to it exists, Python adds Did you mean …?, as for uper above. What each error usually means, and where to look first:

Error It usually means Look first at
NameError A name is used that was never assigned, or is misspelt The spelling, and whether the line that assigns it ran first
TypeError A value of the wrong type for the operation, such as text plus a number The types involved: convert with int(), float() or str()
ValueError The right type with a value that does not fit, such as int("three") The data, often what the user typed or a file contained
IndexError A position past the end of a list: the last one is len(items) - 1 A loop or a calculation that goes one step too far
KeyError A dictionary has no such key; the message is the key The key’s spelling, or use .get() when it may be missing
AttributeError The object has no method or attribute of that name The spelling, and the object’s type: print(type(value))
ZeroDivisionError Division by zero Counts and lengths that can be 0, such as an empty list
ModuleNotFoundError No module of that name for this Python The spelling, and whether the package is installed in the environment you run
IndentationError Indentation that does not match the blocks A missing indented line after a colon, or tabs mixed with spaces
RecursionError A function kept calling itself, by default about 1,000 levels deep The case that should stop the recursion

A common mistake: a file named after a module

Name your own file after a module you import, such as random.py, and Python imports your file instead of the module. Python 3.13 and newer notice and say so:

A file called random.py Python · shadow/random.py
import random

print("Your dice roll:", random.randint(1, 6))

Output (exit status 1)

Printed as an error (standard error)

Traceback (most recent call last):
  File "random.py", line 1, in <module>
    import random
  File "random.py", line 3, in <module>
    print("Your dice roll:", random.randint(1, 6))
                             ^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming 'random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 random.py

The script imports itself as random, so random.randint does not exist. The message even names the file to rename: call it dice.py and import random finds the standard library’s module again. Python 3.12 and older report the same mistake only as a “partially initialized module” and a possible circular import.

Clearer messages in Python 3.14

Python 3.14 improved several other messages too. Using a list as a dictionary key fails, as before, because keys must be hashable and a list, which can change, is not; but the message now says what you tried to do:

A list as a dictionary key Python · unhashable.py
stock = {}
stock[["tea", "toast"]] = 2

Output (exit status 1)

Printed as an error (standard error)

Traceback (most recent call last):
  File "unhashable.py", line 2, in <module>
    stock[["tea", "toast"]] = 2
    ~~~~~^^^^^^^^^^^^^^^^^^
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 unhashable.py

Version note

Python 3.13 and older stop at TypeError: unhashable type: 'list'. Two older improvements show in every traceback of this lesson: since Python 3.11 the ~ and ^ marks point at the exact part of a line that failed (PEP 657), and since Python 3.13 tracebacks in a terminal are in colour, which the environment variables PYTHON_COLORS=0 and NO_COLOR=1 turn off. The pages of What’s New list every improvement, version by version.

When you are stuck

  1. Read the last line slowly and look the exception up on the Built-in Exceptions page of the Python documentation. In the shell, help() shows the documentation of a function, a type or a module, and issubclass() tells you which broader kind of error an exception belongs to:

    Asking Python itself Python console · help_session.pycon
    >>> help(len)
    Help on built-in function len in module builtins:
    
    len(obj, /)
        Return the number of items in a container.
    
    >>> issubclass(KeyError, LookupError)
    True
    >>> issubclass(ModuleNotFoundError, ImportError)
    True

    This session was replayed with Python 3.14.8 on macOS 26 arm64, and it printed exactly what is shown.

  2. Print what you have. Just above the failing line, add print(repr(value), type(value)) for the values it uses. Most surprises are a value of a different type, or text with a space you cannot see.

  3. Make a minimal example. Copy the program and delete everything that is not needed to make the error happen, until only a few lines are left. You often find the bug on the way; if not, those few lines are what you show when you ask for help.

  4. Search for the last line, leaving out the names and values that are particular to your program.

Security

Before you paste code or a traceback into a forum or an AI assistant, take out passwords, API keys, tokens and personal data. Tracebacks contain file paths, which often include your user name, and the code around each failing line.

Python Online Compiler Run bill.py in your browser, select a line of its traceback to jump to that line, and fix the order.

Key takeaways

  • Read a traceback from the bottom: the exception and its message, then the line that failed, then the calls above it.
  • The bug is often higher up than the failing line: follow the bad value back to where it came from, and skip the frames inside libraries.
  • A SyntaxError means nothing ran; when the line shown looks fine, look for an unclosed bracket or quote before it.
  • Python 3.14 suggests misspelt keywords and explains unhashable keys; Did you mean …? hints for names and attributes are older.
  • Get unstuck with the documentation and help(), a print() of the values involved, and a minimal example, and never paste secrets into a question.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.