pythonseverity: can-fix
NameError

Python NameError: name 'X' is not defined

NameError: name 'X' is not defined

99% fixable~3 mindifficulty: beginner

Verified against CPython 3.13 source (Python/ceval.c, LOAD_NAME), Python docs: tutorial/classes (scopes), Python docs: built-in-exceptions · Updated April 2026

> quick_fix

Python can't find a variable, function, or class with that name in the current scope. Check spelling, verify the import statement ran, confirm the variable is defined before use, or that you're not inside a function looking for an enclosing-scope variable.

# NameError - typo
prnt('hello')

# Fix - correct spelling
print('hello')

# NameError - used before defined
total = compute() + 5
def compute(): return 10

# Fix - define first
def compute(): return 10
total = compute() + 5

What causes this error

Python resolves names at runtime via the LEGB rule: Local scope, then Enclosing function scopes, then Global (module) scope, then Built-ins. If the name isn't found in any of those, NameError fires. Most often it's a typo, a missing import, or code that runs before the name is bound (top-level code referring to a function defined below it).

> advertisementAdSense placeholder

How to fix it

  1. 01

    step 1

    Read the missing name from the error

    NameError: name 'prnt' is not defined - the name in quotes is what Python couldn't find.

  2. 02

    step 2

    Check spelling

    By far the most common cause. print/prnt/prinit. Use your editor's autocomplete or run a linter (ruff, pylint) to catch these statically.

  3. 03

    step 3

    Verify imports ran

    If the name comes from another module, confirm the import statement is at the top of the file and didn't fail silently. import math at the top, then math.pi later.

  4. 04

    step 4

    Check definition order

    Functions and classes defined below their first use cause NameError if called at module top-level before the definition is reached. Move the definition up, or wrap the call in a function that's only called later.

  5. 05

    step 5

    For class attribute references inside methods, use self

    Inside a method, instance attributes are accessed as self.attr, not attr. Forgetting self causes NameError when the local scope has no matching name.

    class User:
        def __init__(self, name):
            self.name = name
        def greet(self):
            return f'Hi, {self.name}'

How to verify the fix

  • NameError no longer fires.
  • All names resolve to the expected value.
  • Linter (ruff check) reports no undefined names.

Why NameError happens at the runtime level

Python resolves a free name via the LOAD_NAME or LOAD_GLOBAL bytecode instructions in Python/ceval.c. LOAD_NAME first checks the local namespace (frame->f_locals), then the global namespace (frame->f_globals), then the builtins module. LOAD_GLOBAL is similar but skips locals. If none of these dictionaries contain the key, the interpreter calls _PyErr_Format with PyExc_NameError naming the missing key. Class-body code uses LOAD_NAME (sees enclosing scope), function bodies use LOAD_FAST/LOAD_GLOBAL (compiled by the parser based on whether the name is assigned in the function). The error path is unconditional once all three dicts miss.

Common debug mistakes for NameError

  • Importing a function inside an if-block that didn't run - the import never happened, so the name is undefined when used later.
  • Forgetting to declare a global before assigning to it inside a function - the assignment makes the name local, then reading it before assignment raises UnboundLocalError (a NameError subclass) which is easy to confuse with a typo.
  • Using a list comprehension's loop variable outside it - in Python 3, the variable doesn't leak; accessing it after the comprehension raises NameError.
  • Calling a method on what looks like a bare name when it's actually missing self - this isn't really NameError, it's the local scope not having the attribute, and Python's error is misleading.
  • Defining functions in conditional branches and calling them outside - if the condition was false, the def never ran and the name is undefined.

When NameError signals a deeper problem

Frequent NameError in a codebase points to undisciplined imports and module structure. When developers rely on star-imports or import inside function bodies, the static set of available names becomes ambiguous and editor tools can't catch typos. The architectural fix is enforced top-of-file imports (ruff's I rules), no star-imports (F405), and a typed module structure where every public symbol is declared in __all__. Combined with a CI check that runs ruff and mypy on every commit, NameError becomes impossible to ship. Without it, the error returns silently in untested branches and only fires for the user.

Frequently asked questions

What's the difference between NameError and UnboundLocalError?

NameError - the name doesn't exist anywhere in scope. UnboundLocalError - the name is local to the function (because of an assignment somewhere in the function), but you're reading it before the assignment runs. Subtype of NameError.

Why does Python use the LEGB rule?

It mirrors lexical scoping in most languages while still allowing dynamic redefinition. Built-ins are searched last so you can shadow them locally if needed (though you usually shouldn't).

How do I avoid NameError in production?

Run a linter on every commit (ruff is fast). Use type checkers (mypy, pyright) which flag undefined names statically. Write tests that exercise every code path.

disclosure:Errordex runs AdSense, has zero third-party affiliate or sponsored links, and occasionally links to the editor’s own paid digital products (clearly labelled). Every fix is manually verified against official sources listed in the “sources” sidebar. If a fix here didn’t work for you, please email so we can update the page.