NameError in Python: where it comes from and how to fix it

NameError happens when Python meets a name it does not know: an undefined variable, a typo, a forgotten import.
5 min read
Believemy logo

Definition

The script had been running just fine until this line, and suddenly Python stops cold, complaining about a name it does not recognize. That is exactly what NameError means: while running this particular line, the interpreter looks for a variable, a function, or a module with that name, and finds nothing anywhere in the program.

The difference from a SyntaxError shows up immediately in practice. A syntax error keeps the file from even starting, because its shape is invalid before any execution takes place. A NameError, on the other hand, lets the program run normally, sometimes for a while, before it stumbles on the faulty line: the code reads perfectly, only this one name does not exist.

Here is the plainest version of the problem, a variable name that was simply mistyped:

PYTHON
print(totl)

# NameError: name 'totl' is not defined. Did you mean: 'total'?

Since version 3.10, Python often adds that suggestion in parentheses. It compares the faulty name against every name already known in the program and offers the closest match, which settles half the cases without even rereading the whole file.


The four causes

This single message actually covers four quite different situations, and knowing which one is at play saves real time. The table below sums up how to spot each at a glance, before looking closely at the trickiest one.

CauseTelltale sign
TypoThe suggested name looks like yours
Module not importedThe name is a library name
Variable defined in another functionThe name exists elsewhere in the file
Variable created in a branch not takenThe program works sometimes

The first two causes get fixed within seconds once spotted: correct the spelling, or add the missing import at the top of the file. The third just takes remembering that a function never sees the variables of another function, even a neighbouring one: each one lives in its own space.

The fourth cause deserves closer attention, because it does not show up on every run. A variable assigned only inside an if exists only if the condition happened to be true that time. The program can therefore work smoothly dozens of times in a row, then stop dead the day the data takes the other path.

PYTHON
if balance > 0:
    message = "Credit available"

print(message)   # NameError when the balance is zero
Warning

This kind of NameError often sails through tests, because test data rarely happens to land on the edge case. It resurfaces in production, on the first real piece of data that takes the branch nobody had exercised until then.

The remedy is to give the variable a default value before the condition, or to close the structure with an else that systematically covers every remaining case.


Its cousin, UnboundLocalError

A more confusing variant exists, one that touches a variable which appears to already exist right in front of you. When a function assigns a variable anywhere in its body, Python decides that variable is local to the whole function, including the lines that come before the assignment itself. Reading it earlier then raises an UnboundLocalError, even though a variable of the same name genuinely exists at module level.

PYTHON
counter = 0

def increment():
    print(counter)   # UnboundLocalError, not 0
    counter = counter + 1

Nothing about reading print(counter) on its own gives the problem away: the global variable is set to 0. It is the following line, the one that assigns counter, that retroactively turns the whole function body into local territory, from start to finish.

Good to know

To read and change a global variable from inside a function, it has to be declared with global before it is used. Without that declaration, any assignment inside the function body creates a separate local variable, even one carrying the same name as a module-level variable.


The three-second diagnosis

The message always gives the faulty name in quotes, which makes the rest much easier. Three quick checks are enough, in this order: is the name spelled the same way everywhere it appears, is the matching import sitting at the top of the file, and is the variable defined on every path that leads to that line.

If all three checks turn up nothing, what remains is scope: the variable exists somewhere, just not in the function that is looking for it. Two functions share nothing, so the value has to be passed in as an argument and handed back with return.


Frequently asked questions

Question

How does it differ from AttributeError?

NameError is about a name Python cannot find anywhere in the program, while an AttributeError is about a well-known object being asked for something it does not have. The first message talks about a missing name, the second about a specific object and an attribute it lacks.

Question

Why does my loop variable no longer exist afterwards?

If the sequence being walked through was empty, the loop made no turn at all, so the variable that would have been created inside it never came into being. Over a non-empty sequence, by contrast, it survives the loop quietly and keeps the last value it took.

Question

How can these errors be caught before running the code at all?

An editor properly set up for Python underlines unknown names as they are typed, and static analysis tools flag them across an entire project within seconds. This is the kind of mistake no team should ever discover in production.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.