pandas-dev/pandas · error · UndefinedVariableError
name '{name}' is not defined
Error message
name '{name}' is not defined What it means
Raised as UndefinedVariableError by Scope.resolve when a name used in an eval/query expression cannot be found in locals, resolvers, the global scope, or the temporaries map. The message 'name X is not defined' mirrors Python's own NameError and is pandas' way of telling you the identifier is neither a column nor a bound variable.
Source
Thrown at pandas/core/computation/scope.py:245
if is_local:
return self.scope[key]
# not a local variable so check in resolvers if we have them
if self.has_resolvers:
return self.resolvers[key]
# if we're here that means that we have no locals and we also have
# no resolvers
assert not is_local and not self.has_resolvers
return self.scope[key]
except KeyError:
try:
# last ditch effort we look in temporaries
# these are created when parsing indexing expressions
# e.g., df[df > 0]
return self.temps[key]
except KeyError as err:
raise UndefinedVariableError(key, is_local) from err
def swapkey(self, old_key: str, new_key: str, new_value=None) -> None:
"""
Replace a variable name, with a potentially new value.
Parameters
----------
old_key : str
Current variable name to replace
new_key : str
New variable name to replace `old_key` with
new_value : object
Value to be replaced along with the possible renaming
"""
if self.has_resolvers:
maps = self.resolvers.maps + self.scope.maps
else:
maps = self.scope.mapsView on GitHub (pinned to 3b7651241d)
Solutions
- Prefix local variable references with @: df.query('@x > 0') instead of df.query('x > 0').
- Verify the column name exists: print(df.columns) and fix typos.
- Pass external variables explicitly via the local_dict/resolvers, or use plain boolean indexing df[df.A > x] which uses normal Python scoping.
- For computed columns, use df.eval with column names only and pass globals via the engine's namespace.
Example fix
// before
x = 5
df.query('A > x') # name 'x' is not defined
// after
x = 5
df.query('A > @x') Defensive patterns
Strategy: validation
Validate before calling
def check_query_names(df, expr, local_names=()):
import re
tokens = set(re.findall(r'@?(\b[A-Za-z_]\w*\b)', expr))
cols = set(df.columns)
locals_ok = {t[1:] for t in re.findall(r'@(\b[A-Za-z_]\w*\b)', expr)}
missing = (tokens - cols - locals_ok) - set(local_names)
if missing:
raise NameError(f'names not defined: {sorted(missing)}') Type guard
def names_resolvable(df, expr, local_scope: dict) -> bool:
import re
used = set(re.findall(r'\b[A-Za-z_]\w*\b', expr))
at_names = set(re.findall(r'@([A-Za-z_]\w*)', expr))
return used.issubset(set(df.columns) | set(local_scope)) and at_names.issubset(set(local_scope)) Try / catch
from pandas.errors import UndefinedVariableError
try:
df.query('A > @x')
except UndefinedVariableError as err:
# x not in locals: bind it or switch to boolean indexing
df[df['A'] > x] Prevention
- Prefix every local-variable reference in query/eval with @.
- Print df.columns and cross-check identifiers before building a query string.
- When in doubt, use df[df['A'] > x] which uses normal Python scoping.
When it happens
Trigger: df.query('foo > 0') where foo is not a column and not a local; df.eval('bar + 1') with bar undefined; referencing a local variable without the @ prefix (df.query('@x > 0') is required for locals); a typo in a column name; referencing a variable defined in a different frame.
Common situations: Forgetting the @ prefix to reference local variables in query/eval; misspelling a column name; expecting a variable from an outer scope that wasn't passed into the eval context; version changes that tightened name resolution.
Related errors
- Variables in expression "{expr}" overlap with builtins: ({s}
- Invalid engine '{engine}' passed, valid engines are {valid_e
- The '@' prefix is not allowed in top-level eval calls. pleas
- '{node_name}' nodes are not implemented
- Invalid function call {node.func.id}
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/5941faaba62da0e1.
Report an issue: GitHub.