pandas-dev/pandas · error · ValueError

multi-line expressions are only valid in the context of…

Error message

multi-line expressions are only valid in the context of data, use DataFrame.eval

What it means

Raised in the public eval() function when the expression string contains multiple lines (splitlines yields more than one non-empty line) but no target object is supplied. Multi-line expressions are only meaningful when there is a target (e.g., a DataFrame) to assign results into, because each line typically assigns a new column. Without a target, the multi-line semantics (which expect assignment) are undefined at top level.

Solutions

  1. Use DataFrame.eval for multi-line expressions: df.eval('a = 1\nb = 2') — the DataFrame is the target.
  2. If using pd.eval, pass target=<your DataFrame or dict-like object>.
  3. Split the expression into separate single-line pd.eval calls if you genuinely have no target.

Example fix

// before
pd.eval('new = col_a + col_b\nother = new * 2')

// after
df.eval('new = col_a + col_b\nother = new * 2')
Defensive patterns

Strategy: validation

Validate before calling

is_multiline = isinstance(expr, str) and len([l for l in expr.splitlines() if l.strip()]) > 1
if is_multiline and target is None:
    raise ValueError('Multi-line expressions require a target — use df.eval')
pd.eval(expr, target=target)

Try / catch

try:
    pd.eval(expr, target=target)
except ValueError as e:
    if 'multi-line' in str(e).lower():
        result = df.eval(expr)
    else:
        raise

Prevention

When it happens

Trigger: Calling pd.eval('a = 1\nb = 2') with target=None (the default). Also triggered by expressions with embedded newlines from triple-quoted strings or from files.

Common situations: Using a multi-line expression string built for DataFrame.eval but calling pd.eval by mistake; building a list of expressions joined with newlines and forgetting to pass target=df.

Related errors


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

Appendix: source

Thrown at pandas/core/computation/eval.py:349

    1    pig   20          40
    """
    inplace = validate_bool_kwarg(inplace, "inplace")

    exprs: list[str | BinOp]
    if isinstance(expr, str):
        _check_expression(expr)
        exprs = [e.strip() for e in expr.splitlines() if e.strip() != ""]
    elif isinstance(expr, NDFrame):
        # GH#16289 a Series/DataFrame would otherwise be converted to its
        #  (possibly truncated) repr and parsed, producing a confusing error
        raise ValueError(f"expr must be a string to be evaluated, {type(expr)} given")
    else:
        # ops.BinOp; for internal compat, not intended to be passed by users
        exprs = [expr]
    multi_line = len(exprs) > 1

    if multi_line and target is None:
        raise ValueError(
            "multi-line expressions are only valid in the "
            "context of data, use DataFrame.eval"
        )
    engine = _check_engine(engine)
    _check_parser(parser)
    _check_resolvers(resolvers)

    ret = None
    first_expr = True
    target_modified = False

    for expr in exprs:
        expr = _convert_expression(expr)
        _check_for_locals(expr, level, parser)

        # get our (possibly passed-in) scope
        env = ensure_scope(
            level + 1,

View on GitHub (pinned to 3b7651241d)