pandas-dev/pandas · error · ValueError
Cannot return a copy of the target
Error message
Cannot return a copy of the target
What it means
Raised when inplace=False, an assignment exists, and the target object does not support .copy(). When returning a copy (the default for inplace=False), pandas calls target.copy() (or target.copy(deep=False) for NDFrame) so the original is not mutated. If the target is a type without a .copy() method (e.g., an int, a plain list used as a target, or a custom object), the AttributeError is caught and re-raised as this ValueError.
Solutions
- Use a DataFrame or dict as the target: pd.eval('x = 1', target={}) or target=df.
- Pass inplace=True to avoid the copy step — but only if you intend to mutate the original target in place.
- Wrap your target in a type that supports .copy() (e.g., a dict or a custom class with a copy method).
Example fix
// before
pd.eval('x = 1', target=5)
// after
target = {}
pd.eval('x = 1', target=target) # returns {'x': 1} Defensive patterns
Strategy: type-guard
Validate before calling
if target is not None and not hasattr(target, 'copy'):
raise TypeError(f'target {type(target).__name__} must support .copy() when inplace=False')
pd.eval(expr, target=target, inplace=False) Type guard
def is_copyable_target(t) -> bool:
return t is None or hasattr(t, 'copy') Try / catch
try:
pd.eval(expr, target=target)
except ValueError as e:
if 'Cannot return a copy' in str(e):
result = pd.eval(expr, target=target, inplace=True)
else:
raise Prevention
- Use DataFrame or dict as target.
- Avoid passing scalars or immutable types as target.
- Validate target supports .copy() for inplace=False.
When it happens
Trigger: Calling pd.eval('x = 1', target=5, inplace=False) where target is an int — ints have no .copy(). Or target=some_list where list.copy exists but a different non-copyable object was passed.
Common situations: Using a plain Python object (int, tuple, or a namespace object) as a target for pd.eval assignment instead of a DataFrame, dict, or other copyable container; experimentation with target types.
Related errors
- Cannot assign expression output to target
- cannot assign without a target object
- can only assign a single expression
- Cannot operate inplace if there is no assignment
- left hand side of an assignment must be a single name
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/709c7baff902ec36.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/eval.py:425
)
if inplace:
raise ValueError("Cannot operate inplace if there is no assignment")
# assign if needed
assigner = parsed_expr.assigner
if env.target is not None and assigner is not None:
target_modified = True
# if returning a copy, copy only on the first assignment
if not inplace and first_expr:
try:
target = env.target
if isinstance(target, NDFrame):
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:View on GitHub (pinned to 3b7651241d)