Python NameError: name is not defined
Fix Python NameError when a variable or function is referenced before it is defined, or is out of scope inside a function or class.
Symptoms
- NameError: name 'x' is not defined
- A function works at module level but fails when moved into another function
- NameError appears only on the first call or under a specific branch
Possible causes
- The variable is used before its assignment line executes
- A local variable shadows a global one inside a function, so the global is undefined there
- A typo or wrong capitalization differs from the defined name
- A class attribute is used as if it were a bare name inside a method
Diagnosis steps
Note the exact name and traceback line
Interpretation
Python reports the missing name and the line; check whether that line runs before the binding.
Print the module globals to see what exists
print(sorted(globals().keys()))Interpretation
If the name is absent from globals and not local, it was never defined on this path.
Check for shadowing by a local assignment
Interpretation
If any function assigns to the name, Python treats it as local for the whole function, making earlier reads fail.
Root cause
Python resolves names at runtime. A name must be bound before the line that reads it executes, and inside a function any assignment makes the name local to that entire function. Referencing a name that was never assigned on this execution path, or that is local due to a later assignment, raises NameError.
Fix
Move the definition above its first use, initialise the variable on all branches, and add `global name` (or better, avoid reassigning globals) when a function must modify a module-level binding. Fix typos by cross-checking the traceback name against its definition, and reference class attributes via self.attr.
Verify the fix
Run the failing snippet again; the traceback clears and the value prints. Add a unit test that exercises the previously failing branch to prevent regressions.
Symptoms
You get NameError: name 'x' is not defined. It often appears on a branch that runs before a later assignment, or after code is moved between scopes.
Diagnosis
Read the traceback: it names the missing symbol and the line that read it. Then inspect what actually exists:
def f():
print(sorted(globals().keys()))
return value # NameError if value defined later
If a function assigns to the name anywhere, it is local everywhere in that function.
Fix
Define before use and cover every branch:
value = 0
def f():
global value
value += 1 # needs the global declaration
return value
Avoid global where possible; passing values in and returning them is cleaner.
Verification
Re-run the code and confirm no NameError. Add a test for the branch that used to fail so the fix is locked in.