{"record":{"id":"de107e9f40879483","repo":"pandas-dev/pandas","slug":"expr-must-be-a-string-to-be-evaluated-type-expr","errorCode":null,"errorMessage":"expr must be a string to be evaluated, {type(expr)} given","messagePattern":"expr must be a string to be evaluated, (.+?) given","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/eval.py","lineNumber":342,"sourceCode":"    1    pig   20\n\n    We can add a new column using ``pd.eval``:\n\n    >>> pd.eval(\"double_age = df.age * 2\", target=df)\n      animal  age  double_age\n    0    dog   10          20\n    1    pig   20          40\n    \"\"\"\n    inplace = validate_bool_kwarg(inplace, \"inplace\")\n\n    exprs: list[str | BinOp]\n    if isinstance(expr, str):\n        _check_expression(expr)\n        exprs = [e.strip() for e in expr.splitlines() if e.strip() != \"\"]\n    elif isinstance(expr, NDFrame):\n        # GH#16289 a Series/DataFrame would otherwise be converted to its\n        #  (possibly truncated) repr and parsed, producing a confusing error\n        raise ValueError(f\"expr must be a string to be evaluated, {type(expr)} given\")\n    else:\n        # ops.BinOp; for internal compat, not intended to be passed by users\n        exprs = [expr]\n    multi_line = len(exprs) > 1\n\n    if multi_line and target is None:\n        raise ValueError(\n            \"multi-line expressions are only valid in the \"\n            \"context of data, use DataFrame.eval\"\n        )\n    engine = _check_engine(engine)\n    _check_parser(parser)\n    _check_resolvers(resolvers)\n\n    ret = None\n    first_expr = True\n    target_modified = False\n","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/eval.py#L324-L360","documentation":"pd.eval requires an expression string. A DataFrame or Series passed as expr would otherwise be stringified to its (possibly truncated) repr and then parsed, producing a confusing downstream parse error (GH#16289). pandas short-circuits this with an explicit type guard that names the offending type, so the user sees the real problem instead of a misleading SyntaxError from a truncated repr.","triggerScenarios":"pd.eval(df), pd.eval(some_series), or any code path that programmatically routes a pandas object into the expr slot of pd.eval instead of a string. Also reachable by feeding eval the result of another computation that returns a frame.","commonSituations":"Confusing pd.eval with a generic 'evaluate this object' function. Refactoring code where a variable that used to hold a string now holds a DataFrame. Building expression inputs dynamically and forgetting to stringify.","solutions":["Pass a string expression that references the frame's columns, e.g. pd.eval('a + b').","Operate on the frame directly with vectorized ops (df['a'] + df['b']) or df.eval(...).","If you have a stringified repr, build the expression from column names, not from the frame object."],"exampleFix":"// before\npd.eval(df)\n// after\npd.eval('a + b', local_dict={'a': df['a'], 'b': df['b']})","handlingStrategy":"type-guard","validationCode":"def require_str_expr(expr) -> str:\n    if not isinstance(expr, str):\n        raise TypeError(\n            f'expr must be str, got {type(expr).__name__}; '\n            'pass a column expression string instead'\n        )\n    return expr\n\nexpr = require_str_expr(expr)","typeGuard":"import pandas as pd\n\ndef is_eval_expr_string(expr) -> bool:\n    return isinstance(expr, str) and not isinstance(expr, (pd.DataFrame, pd.Series))","tryCatchPattern":"try:\n    pd.eval(expr)\nexcept ValueError as e:\n    if 'must be a string' in str(e):\n        # operate on the frame directly instead\n        result = expr  # or expr.some_vector_op()\n    else:\n        raise","preventionTips":["Type-check expr at the boundary of any wrapper around pd.eval.","Keep DataFrame/Series operations on the object API, reserving pd.eval for strings.","In dynamic pipelines, assert isinstance(expr, str) before pd.eval."],"tags":["pandas","eval","type-validation","dataframe"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}