pandas-dev/pandas · error · ValueError
keyword error in function call '{node.func.id}'
Error message
keyword error in function call '{node.func.id}' What it means
In the non-FuncNode branch of visit_Call (expr.py:701), each element of node.keywords is expected to be an ast.keyword node. The check at expr.py:705 is defensive: for any syntactically valid Python call, Python's parser always produces ast.keyword entries, so reaching the raise indicates either hand-built/malformed AST or a preparser that injected non-keyword nodes. The message names node.func.id to help locate the offending call.
Source
Thrown at pandas/core/computation/expr.py:708
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]
for key in node.keywords:
if not isinstance(key, ast.keyword):
# error: Item "Attribute" of "Attribute | Name" has no
# attribute "id"
raise ValueError(
f"keyword error in function call '{node.func.id}'" # type: ignore[union-attr]
)
if key.arg:
kwargs[key.arg] = self.visit(key.value)(self.env)
name = self.env.add_tmp(res(*new_args, **kwargs))
return self.term_type(name=name, env=self.env)
def translate_In(self, op):
return op
def visit_Compare(self, node, **kwargs):
ops = node.ops
comps = node.comparators
# base case: we have something like a CMP b
if len(comps) == 1:View on GitHub (pinned to 71959b8cb9)
Solutions
- Avoid constructing ast.Call nodes manually; pass string expressions instead.
- If you must build AST, ensure every keywords entry is an ast.keyword.
- Simplify the expression to a plain positional call and report the edge case upstream.
Example fix
// before
# hand-built ast.Call with a non-keyword entry in node.keywords
// after
# pass a plain string expression so Python's parser builds correct AST:
df.eval('foo(a, b=1)') Defensive patterns
Strategy: validation
Validate before calling
import ast
def validate_keywords_wellformed(expr: str) -> None:
for node in ast.walk(ast.parse(expr, mode='eval')):
if isinstance(node, ast.Call):
for kw in node.keywords:
if not isinstance(kw, ast.keyword):
raise ValueError(
f'malformed keyword node in call {ast.dump(node)}'
)
# this guards only hand-built AST; for string input Python's parser guarantees this
validate_keywords_wellformed(expr) Type guard
import ast
def call_keywords_wellformed(expr: str) -> bool:
return all(
isinstance(kw, ast.keyword)
for n in ast.walk(ast.parse(expr, mode='eval'))
if isinstance(n, ast.Call) for kw in n.keywords
) Try / catch
try:
df.eval(expr)
except ValueError as e:
if 'keyword error in function call' in str(e):
# simplify the call to positional args and retry
df.eval('foo(a, b)')
raise Prevention
- Pass string expressions rather than hand-built AST to pandas eval.
- Avoid custom preparsers that mutate node.keywords structure.
- If you must build AST, ensure every keywords entry is ast.keyword.
When it happens
Trigger: Effectively unreachable from normal string input. Surfaces only with manually constructed ast.Call nodes whose keywords list contains non-ast.keyword items, or with a buggy preparser that mangles the keyword list.
Common situations: Internal tooling or third-party libraries that build AST and feed it to pandas. Debugging custom visitors. Note: the surrounding code also references an uninitialized 'kwargs' dict (expr.py:713), so this region is best treated as internal/defensive.
Related errors
- '{node_name}' nodes are not implemented
- only a single expression is allowed
- Only named functions are supported
- Invalid function call {node.func.id}
- Function "{res.name}" does not support keyword arguments
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/1455bf6e5c763777.
Report an issue: GitHub.