pandas-dev/pandas · error · ValueError
Cannot assign expression output to target
Error message
Cannot assign expression output to target
What it means
After computing the RHS, eval.py:437 does target[assigner] = ret. For NDFrame in the inplace path it uses .loc[:, assigner]; otherwise it relies on __setitem__ with a string key. If the target type can't take a string-keyed item assignment (int, list, np.ndarray raising IndexError, or other containers raising TypeError), the error is caught at eval.py:438 and re-raised as a clearer ValueError.
Source
Thrown at pandas/core/computation/eval.py:439
target = target.copy(deep=False)
else:
target = target.copy()
except AttributeError as err:
raise ValueError("Cannot return a copy of the target") from err
else:
target = env.target
# TypeError is most commonly raised (e.g. int, list), but you
# get IndexError if you try to do this assignment on np.ndarray.
# we will ignore numpy warnings here; e.g. if trying
# to use a non-numeric indexer
try:
if inplace and isinstance(target, NDFrame):
target.loc[:, assigner] = ret
else:
target[assigner] = ret # pyright: ignore[reportIndexIssue]
except (TypeError, IndexError) as err:
raise ValueError("Cannot assign expression output to target") from err
if not resolvers:
resolvers = ({assigner: ret},)
else:
# existing resolver needs updated to handle
# case of mutating existing column in copy
for resolver in resolvers:
if assigner in resolver:
resolver[assigner] = ret
break
else:
resolvers += ({assigner: ret},)
ret = None
first_expr = False
# We want to exclude `inplace=None` as being False.
if inplace is False:View on GitHub (pinned to 71959b8cb9)
Solutions
- Use a dict or DataFrame as the target, both of which support string-key assignment.
- For array targets, assign into a dict wrapper and pull values out afterwards.
- Use inplace=True with an NDFrame target which routes through .loc[:, assigner].
Example fix
// before
pd.eval('a = 1', target=[])
// after
ns = {}
pd.eval('a = 1', target=ns)
print(ns['a']) Defensive patterns
Strategy: validation
Validate before calling
def validate_target_supports_setitem(target) -> None:
if not hasattr(target, '__setitem__'):
raise ValueError(
f'target {type(target).__name__} cannot accept string-key assignment; '
'use a dict or DataFrame'
)
validate_target_supports_setitem(target) Type guard
def target_supports_str_setitem(target) -> bool:
return hasattr(target, '__setitem__') Try / catch
try:
pd.eval(expr, target=target)
except ValueError as e:
if 'assign expression output' in str(e):
ns = {}
pd.eval(expr, target=ns) # use a dict target instead
else:
raise Prevention
- Use dict or DataFrame targets for assignment expressions.
- Avoid passing lists, ints, or ndarrays as eval targets.
- For NDFrame targets, prefer inplace=True which routes through .loc.
When it happens
Trigger: pd.eval('a = 1', target=[]), pd.eval('a = 1', target=42), or any target whose __setitem__ rejects string keys. Also np.ndarray targets where the string assigner triggers IndexError.
Common situations: Using a non-dict, non-NDFrame object as target. Passing a list expecting it to behave like a namespace. Misconfigured custom resolver objects.
Related errors
- multi-line expressions are only valid in the context of data
- cannot assign without a target object
- Multi-line expressions are only valid if all expressions con
- Cannot operate inplace if there is no assignment
- Cannot return a copy of the target
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/50d1b437898858a0.
Report an issue: GitHub.