pandas-dev/pandas · error · ValueError
Invalid function call
Error message
Invalid function call {node.func.id} What it means
Raised by pandas.eval()/DataFrame.query() when a function call inside the expression string cannot be resolved. The visitor first tries to resolve the name in the user's scope (locals/globals), and on UndefinedVariableError falls back to constructing a FuncNode from the supported MATHOPS list (sin, cos, exp, log, sqrt, abs, ...). If both lookups fail the original undefined-variable error is re-raised; this ValueError fires only when the resolved result is None, meaning the call target is neither a scope variable nor a supported numpy math function.
Solutions
- Replace the unsupported function with one of the whitelisted numpy math functions: sin, cos, tan, exp, log, expm1, log1p, sqrt, sinh, cosh, tanh, arcsin, arccos, arctan, arccosh, arcsinh, arctanh, abs, log10, floor, ceil, arctan2.
- If you need a non-whitelisted function, compute it in Python first and pass the result as a @-prefixed local variable: pre = np.where(A>0, A, 0); df.query('@pre > 1').
- Drop eval/query entirely and use vectorized boolean indexing: df[df['A'].apply(my_func)].
- Check for typos: compare the function name against the MATHOPS tuple in pandas/core/computation/ops.py.
Example fix
// before
df.query("sine(A) > 0.5")
df.query("round(A) > 0")
// after
df.query("sin(A) > 0.5")
rounded = np.round(df['A'])
df[rounded > 0] Defensive patterns
Strategy: validation
Validate before calling
import pandas.core.computation.ops as _ops
SUPPORTED = set(_ops.MATHOPS)
def is_supported_query_fn(name: str) -> bool:
return name in SUPPORTED or name in globals() or name in locals()
# before building the query string
fn = 'sine'
assert is_supported_query_fn(fn), f'{fn} is not a supported eval/query function' Type guard
from typing import Any
import pandas.core.computation.ops as _ops
def is_mathop_call(node: Any) -> bool:
return isinstance(node.func, type(node)) and getattr(node.func, 'id', None) in _ops.MATHOPS Try / catch
try:
df.query('foo(A)')
except (ValueError, UndefinedVariableError) as e:
# fall back to vectorized Python
df[df['A'].apply(foo)] Prevention
- Maintain a constant set of whitelisted math functions and assert query strings only reference those or @-locals.
- Build query strings from a small templating layer that rejects unknown function tokens.
- Run query strings through a dry-run parse on a tiny DataFrame during development.
When it happens
Trigger: Calling df.query('foo(A)') or pd.eval('foo(A)') where 'foo' is not defined in the local/global namespace and is not one of the whitelisted numpy math functions. Also triggered by chained attribute calls where visit_Attribute returns None, or by referencing a function name that shadows a math op but resolves to a non-callable.
Common situations: Typos in function names inside query strings (e.g. 'sine(A)' instead of 'sin(A)'). Attempting to call arbitrary Python/NumPy functions (np.where, len, round, custom ufuncs) inside eval/query, which the engine does not support. Forgetting to prefix a user function with @ (only @-prefixed locals are visible, and even then only callables resolving through the scope path work).
Related errors
- Function " " does not support keyword arguments
- " " is not a supported function
- cannot evaluate scalar only bool ops
- Invalid binary operator
- Invalid unary operator
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/afeb610c372249b6.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/expr.py:685
def visit_Call(self, node, side=None, **kwargs):
if isinstance(node.func, ast.Attribute) and node.func.attr != "__call__":
res = self.visit_Attribute(node.func)
elif not isinstance(node.func, ast.Name):
raise TypeError("Only named functions are supported")
else:
try:
res = self.visit(node.func)
except UndefinedVariableError:
# Check if this is a supported function name
try:
res = FuncNode(node.func.id)
except ValueError:
# Raise original error
raise
if res is None:
# error: "expr" has no attribute "id"
raise ValueError(
f"Invalid function call {node.func.id}" # type: ignore[union-attr]
)
if hasattr(res, "value"):
res = res.value
if isinstance(res, FuncNode):
new_args = [self.visit(arg) for arg in node.args]
if node.keywords:
raise TypeError(
f'Function "{res.name}" does not support keyword arguments'
)
return res(*new_args)
else:
new_args = [self.visit(arg)(self.env) for arg in node.args]
View on GitHub (pinned to 3b7651241d)