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

  1. Use a dict or DataFrame as the target, both of which support string-key assignment.
  2. For array targets, assign into a dict wrapper and pull values out afterwards.
  3. 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

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


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/50d1b437898858a0. Report an issue: GitHub.