Skip to main content

Fix NameError in Python

Error Reference

NameError: name 'x' is not defined

Python can't find that variable, function, or module. Here's how to fix it.

Checklist

  • Spelling? Names are case-sensitive.
  • Defined before use? Move definitions above usage or wrap in functions.
  • Imported? Ensure you actually imported the symbol.
  • Scope? Variables defined inside functions can't be used outside.
  • Quotes? A bare word that should be a string literal raises NameError too.

Typos

The most common NameError is a misspelling — and since Python 3.10, the traceback often spots it for you:

length = 42
print(lenght)
# NameError: name 'lenght' is not defined. Did you mean: 'length'?

Take the suggestion seriously; it compares against every name in scope. Remember that Total, total, and TOTAL are three different names.

Define before use

Top-level code runs strictly top to bottom, so a name must be assigned before the line that reads it:

greet()  # NameError: name 'greet' is not defined

def greet():
print('hello')

Function bodies, however, run at call time — so a function may freely reference names defined later, as long as they exist by the time it's called:

def main():
greet() # fine: 'greet' is looked up when main() runs

def greet():
print('hello')

main() # prints: hello

That's why the standard pattern is: define everything, then call main() at the bottom.

Scope

Variables created inside a function are local — they vanish when the function returns:

def build():
total = 0

build()
print(total) # NameError: name 'total' is not defined

Move the print statement inside build(), or better, return the value:

def build():
total = 0
return total

total = build()
print(total) # 0

The sibling error is UnboundLocalError (itself a subclass of NameError). It appears when you assign to a name inside a function that also exists outside — the assignment makes the name local for the whole function, so reading it before the assignment fails:

count = 0

def increment():
count += 1 # read-then-assign of a local that has no value yet

increment()
# UnboundLocalError: cannot access local variable 'count'
# where it is not associated with a value
# (before Python 3.11: "local variable 'count' referenced before assignment")

Declare global count inside the function if you truly want to mutate the module-level variable — or, usually better, pass the value in and return the new one.

Missing quotes

Writing a string without quotes makes Python treat it as a variable name:

color = blue    # NameError: name 'blue' is not defined
color = 'blue' # a string literal — what you meant

This bites hardest in comparisons: if answer == yes: looks fine at a glance but needs 'yes'.

Frequently Asked Questions

What is the difference between NameError and UnboundLocalError?

UnboundLocalError is a subclass of NameError for one specific case: a name that IS local to the current function (because you assign to it somewhere in the body) is read before that assignment runs. A plain NameError means the name was not found in any scope at all. If you see UnboundLocalError, look for an assignment lower in the same function — that assignment is what made the name local.

count = 0
def increment():
count += 1 # UnboundLocalError: assignment makes 'count' local

Why does my variable from an if block not exist?

An if block does not create a new scope in Python, so the variable would be visible afterwards — if the branch actually ran. When the condition is false, the assignment never executes and the name is never created. Assign a default before the if, or add an else branch, so the name exists on every path.

temperature = 21
if temperature > 30:
warning = 'hot'
print(warning) # NameError: name 'warning' is not defined

# fix: give it a value on every path
warning = ''
if temperature > 30:
warning = 'hot'

Next up in your learning path