1. Symptoms
When a NameError occurs in Python, the interpreter halts execution and displays a traceback that clearly identifies the problem. The error message follows a consistent pattern: NameError: name 'identifier' is not defined, where identifier is the name that Python could not resolve.
Common manifestations:
Traceback (most recent call last):
File "example.py", line 10, in <module>
print(my_variable)
NameError: name 'my_variable' is not defined
Traceback (most recent call last):
File "calculator.py", line 15, in <module>
result = add_numbers(a, b)
NameError: name 'add_numbers' is not defined
The error always appears at the exact line where Python attempts to access the undefined name. The line number in the traceback pinpoints the location, making initial diagnosis straightforward. However, the root cause might be earlier in the code—perhaps a typo made hours ago that only manifests when execution reaches the problematic line.
Typical symptoms include:
- Unexpected
NameErrorduring script execution - Code that worked previously suddenly failing
- Errors appearing only under certain conditions
- Errors in imported modules referencing names not defined in those modules
2. Root Cause
Python’s NameError occurs during the execution phase when the interpreter attempts to resolve a name that has not been defined in the current scope. Python uses a LEGB rule for name resolution: Local → Enclosing → Global → Built-in. When a name cannot be found in any of these scopes, Python raises NameError.
Primary causes:
-
Typographical errors in variable names - The most common cause. Python is case-sensitive, so
MyVariable,myvariable, andmy_variableare three distinct names. -
Using a variable before assignment - Referencing a variable in a function before it has been assigned a value.
-
Missing import statements - Attempting to use functions from modules that have not been imported.
-
Scope-related issues - Trying to access variables defined in different scopes.
-
Conditional definition - Variables defined only inside conditional blocks that weren’t executed.
-
Misspelled built-in functions - Accidentally using
pint()instead ofprint(). -
Class or function not yet defined - Calling functions or instantiating classes defined later in the code (when not using forward references).
-
Circular imports - Import issues that manifest as
NameErrorwhen modules reference each other.
Understanding why NameError occurs requires examining Python’s two-phase execution model: first the compiler performs syntax checking and creates bytecode, then the interpreter executes the bytecode. Name resolution happens exclusively during execution, which is why NameError is a runtime error rather than a compile-time error.
3. Step-by-Step Fix
Step 1: Identify the undefined name
The error message clearly states which name is undefined. Look for the specific identifier between quotes in name 'identifier' is not defined.
Step 2: Locate all occurrences of the name
Search your codebase for the problematic identifier to understand where it’s used and where it should be defined.
Step 3: Determine the intended value or definition
Decide whether this should be a variable, function, class, or imported module member.
Step 4: Apply the appropriate fix
Fix 1: Define the variable
# BROKEN CODE
def calculate_total():
subtotal = 100
tax = 10
return total # NameError: name 'total' is not defined
result = calculate_total()
print(result)
Before:
def calculate_total():
subtotal = 100
tax = 10
return total # NameError: name 'total' is not defined
result = calculate_total()
print(result)
After:
def calculate_total():
subtotal = 100
tax = 10
total = subtotal + tax # Define 'total' before using it
return total
result = calculate_total()
print(result) # Output: 110
Fix 2: Add missing import statement
# BROKEN CODE
def format_date(date_obj):
return date_obj.strftime("%Y-%m-%d")
today = datetime.now() # NameError: name 'datetime' is not defined
print(format_date(today))
Before:
def format_date(date_obj):
return date_obj.strftime("%Y-%m-%d")
today = datetime.now()
print(format_date(today))
After:
from datetime import datetime # Import statement added
def format_date(date_obj):
return date_obj.strftime("%Y-%m-%d")
today = datetime.now()
print(format_date(today)) # Output: 2024-01-15
Fix 3: Correct typos
# BROKEN CODE
def calculate_area(width, height):
return width * haight # Typo: 'haight' instead of 'height'
area = calculate_area(5, 10)
print(f"Area: {area}")
Before:
def calculate_area(width, height):
return width * haight # Typo
area = calculate_area(5, 10)
print(f"Area: {area}")
After:
def calculate_area(width, height):
return width * height # Fixed typo
area = calculate_area(5, 10)
print(f"Area: {area}") # Output: Area: 50
Fix 4: Handle conditional variable definition
# BROKEN CODE
def get_discount_price(price, is_member):
if is_member:
discount_price = price * 0.9
return discount_price # NameError if is_member is False
final_price = get_discount_price(100, False)
print(final_price)
Before:
def get_discount_price(price, is_member):
if is_member:
discount_price = price * 0.9
return discount_price # NameError if is_member is False
final_price = get_discount_price(100, False)
print(final_price)
After:
def get_discount_price(price, is_member):
discount_price = price # Initialize with default value
if is_member:
discount_price = price * 0.9
return discount_price
final_price = get_discount_price(100, False)
print(final_price) # Output: 100
4. Verification
After applying the fix, verify the solution by running the code again:
python example.py
Expected output: The script should execute without any NameError traceback.
Verification checklist:
- Run the specific test case that previously triggered the error
- Test edge cases including
False,None, empty collections, and zero values - Check all code paths to ensure no other
NameErrorinstances exist - Run unit tests if available:
python -m pytestorpython -m unittest - Use a linter to catch potential issues:
python -m py_compile your_script.py
Automated verification script:
def verify_fix():
"""Run the code that previously raised NameError."""
try:
# Replace with the code that was failing
from datetime import datetime
today = datetime.now()
result = today.strftime("%Y-%m-%d")
print(f"Success: Date formatted as {result}")
return True
except NameError as e:
print(f"NameError still present: {e}")
return False
if __name__ == "__main__":
verify_fix()
IDE-based verification:
Most modern IDEs (VS Code, PyCharm, etc.) highlight undefined names with red underlines in real-time. If your IDE doesn’t show this, ensure you have Pylint or a similar linter installed and enabled.
5. Common Pitfalls
Pitfall 1: Case sensitivity
Python is case-sensitive. True, TRUE, and true are three different identifiers. Built-in constants like True, False, and None must use exact casing.
# BROKEN
is_active = TRUE # NameError: name 'TRUE' is not defined
# CORRECT
is_active = True # Built-in constant
Pitfall 2: Global vs. local scope
Variables defined outside functions are global; variables defined inside functions are local. Attempting to read a local variable before assignment raises NameError.
# BROKEN
def process_data():
print(data) # NameError: data referenced before assignment
data = [1, 2, 3]
# CORRECT
def process_data():
data = [1, 2, 3] # Define before use
print(data)
process_data() # Output: [1, 2, 3]
Pitfall 3: Circular imports
Module A imports from Module B while Module B imports from Module A, causing names to be undefined at runtime.
# module_a.py
from module_b import helper # May fail if module_b hasn't finished loading
# module_b.py
from module_a import processor # Both modules trying to import each other
Solution: Restructure imports, use late imports inside functions, or use absolute imports with proper package structure.
Pitfall 4: Function name shadowing
Naming a variable the same as a built-in function can cause confusion.
# BROKEN
list = [1, 2, 3] # Shadows built-in 'list'
numbers = list(range(5)) # NameError: 'list' is now a variable, not a function
# CORRECT
numbers_list = [1, 2, 3] # Don't shadow built-ins
numbers = list(range(5))
Pitfall 5: String quotes vs. variable names
Beginners sometimes forget that names inside quotes are strings, not variable references.
# BROKEN
variable_name = "value"
print("variable_name") # Prints the string, not the variable
# CORRECT
variable_name = "value"
print(variable_name) # Prints "value"
Pitfall 6: String formatting errors
Using incorrect f-string syntax can lead to unexpected behavior.
# BROKEN
name = "Alice"
print(f"Hello, {name}") # This works correctly
print(f"Hello, {name}") # Missing 'f' prefix - treats as regular string
6. Related Errors
UnboundLocalError
A subclass of NameError that specifically indicates a local variable was referenced before assignment within a function. Python treats variables assigned within a function as local, so reading them before assignment raises this specific error.
def example():
print(x) # UnboundLocalError: local variable 'x' referenced before assignment
x = 10
example()
NameError: name ‘…’ is not defined
The exact error message format. Variations include:
NameError: name 'None' is not defined(incorrect use of None)NameError: name '__name__' is not defined(context-specific built-ins)
AttributeError
Often confused with NameError when accessing attributes. If the base object doesn’t exist, you’ll see NameError; if the attribute doesn’t exist on a valid object, you’ll see AttributeError.
# NameError if 'non_existent_module' doesn't exist
# AttributeError if the module exists but lacks the attribute
import os
os.non_existent_function() # AttributeError: module 'os' has no attribute 'non_existent_function'
ImportError
Manifests when trying to import names that don’t exist in the target module. This can appear as NameError in imported code.
from collections import OrderedDict # Works
from collections import ChainMap # ImportError: cannot import name 'ChainMap' (in older Python versions)
Key differences:
| Error | Cause | Resolution |
|---|---|---|
NameError |
Name not defined in any scope | Define the variable or import it |
UnboundLocalError |
Local variable used before assignment | Initialize before use |
AttributeError |
Attribute doesn’t exist on object | Check object type or attribute name |
ImportError |
Module or name doesn’t exist | Verify module installation or name |
Prevention strategies:
- Use IDE with real-time error checking
- Run linters (Pylint, Flake8) in your CI/CD pipeline
- Write unit tests to catch undefined references
- Follow PEP 8 naming conventions consistently
- Use type hints (Python 3.5+) to catch naming issues early
# Type hints can help catch errors
def greet(name: str) -> str:
return f"Hello, {nmae}" # IDE may catch this typo if configured
# Refactored with correct name
def greet(name: str) -> str:
return f"Hello, {name}"