pandas-dev/pandas · error · ValueError

Cannot assign expression output to target

Error message

Cannot assign expression output to target

What it means

Raised when the assignment to the target fails with TypeError or IndexError during target[assigner] = ret (or target.loc[:, assigner] = ret for inplace NDFrame). This happens when the target object does not support item assignment with a string key (e.g., assigning to a list with a non-integer key), or when the numpy ndarray raises IndexError for the assignment. The original TypeError/IndexError is chained via 'from err'.

Solutions

  1. Use a dict or DataFrame as the target — both support string-key assignment: pd.eval('x = 1', target={}).
  2. Ensure the result shape aligns with the target (e.g., the assigned Series length matches the DataFrame rows).
  3. If targeting a numpy array, use an integer index or wrap it in a DataFrame.

Example fix

// before
pd.eval('x = 1', target=[])

// after
pd.eval('x = 1', target={})
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import MutableMapping
import pandas as pd
if target is not None and not isinstance(target, (MutableMapping, pd.DataFrame, pd.Series)):
    raise TypeError(f'target {type(target).__name__} must support string-key item assignment')
pd.eval(expr, target=target)

Type guard

def supports_string_key_assignment(t) -> bool:
    try:
        t['__probe__'] = None
        del t['__probe__']
        return True
    except (TypeError, KeyError):
        return False

Try / catch

try:
    pd.eval(expr, target=target)
except ValueError as e:
    if 'Cannot assign' in str(e):
        # switch to a dict target
        new_target = {}
        pd.eval(expr, target=new_target)
    else:
        raise

Prevention

When it happens

Trigger: Using target=int or target=list where string-key assignment is unsupported: pd.eval('x = 1', target=[]) raises TypeError on list['x']=1. Also triggered when the result shape mismatches the target for numpy arrays (IndexError).

Common situations: Passing an incompatible target type; assigning a result whose length/dtype does not match the target's existing structure; using a target that is a tuple (immutable, raises TypeError on assignment).

Related errors


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

Appendix: 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 3b7651241d)