{"record":{"id":"f8a1d91a1fe51888","repo":"pandas-dev/pandas","slug":"unsupported-operand-type-s-for-res-op-lhs-ty","errorCode":null,"errorMessage":"unsupported operand type(s) for {res.op}: '{lhs.type}' and '{rhs.type}'","messagePattern":"unsupported operand type\\(s\\) for (.+?): '(.+?)' and '(.+?)'","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/computation/expr.py","lineNumber":512,"sourceCode":"        # in that case a + 2 * b will be evaluated using numexpr, and the \"in\"\n        # call will be evaluated using isin (in python space)\n        return binop.evaluate(\n            self.env, self.engine, self.parser, self.term_type, eval_in_python\n        )\n\n    def _maybe_evaluate_binop(\n        self,\n        op,\n        op_class,\n        lhs,\n        rhs,\n        eval_in_python=(\"in\", \"not in\"),\n        maybe_eval_in_python=(\"==\", \"!=\", \"<\", \">\", \"<=\", \">=\"),\n    ):\n        res = op(lhs, rhs)\n\n        if res.has_invalid_return_type:\n            raise TypeError(\n                f\"unsupported operand type(s) for {res.op}: \"\n                f\"'{lhs.type}' and '{rhs.type}'\"\n            )\n\n        if self.engine != \"pytables\" and (\n            (res.op in CMP_OPS_SYMS and getattr(lhs, \"is_datetime\", False))\n            or getattr(rhs, \"is_datetime\", False)\n        ):\n            # all date ops must be done in python bc numexpr doesn't work\n            # well with NaT\n            return self._maybe_eval(res, self.binary_ops)\n\n        if res.op in eval_in_python:\n            # \"in\"/\"not in\" ops are always evaluated in python\n            return self._maybe_eval(res, eval_in_python)\n        elif self.engine != \"pytables\":\n            if (\n                getattr(lhs, \"return_type\", None) == object","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/computation/expr.py#L494-L530","documentation":"In _maybe_evaluate_binop, after constructing the BinOp the code checks res.has_invalid_return_type (expr.py:511). When the operand types are incompatible for the operator (e.g. numexpr can't add a string array to a bool array, or the dtypes have no valid common result), the flag is set and a TypeError is raised naming the operator and both operand types. This is the type-mismatch guard for binary operations across the supported operator set.","triggerScenarios":"df.eval('a + b') where 'a' is object/string dtype and 'b' is bool, or any binary op whose operand return_types the engine deems incompatible. Also mixing datetime with numeric in unsupported ops.","commonSituations":"Object-dtype columns holding mixed types. String columns participating in arithmetic. Missing dtype conversions after reading CSVs. Version changes in numexpr's accepted type matrix.","solutions":["Cast the offending columns with astype to a compatible numeric dtype before eval.","Switch to engine='python' which is more permissive for object-dtype arithmetic.","Drop or separate the incompatible columns and compute them outside eval."],"exampleFix":"// before\ndf.eval('a + b')  # a is str, b is bool\n// after\ndf['a_num'] = pd.to_numeric(df['a'], errors='coerce')\ndf.eval('a_num + b')","handlingStrategy":"validation","validationCode":"def validate_compatible_dtypes(df, expr_cols_per_op) -> None:\n    for left, right in expr_cols_per_op:\n        ld, rd = df[left].dtype, df[right].dtype\n        if ld == object or rd == object:\n            raise TypeError(\n                f'cannot combine object-dtype columns {left} ({ld}) and {right} ({rd}); cast first'\n            )\n\n# or broadly: check dtypes of every column referenced in the expression\n","typeGuard":"def columns_are_numeric(df, cols) -> bool:\n    import pandas.api.types as pt\n    return all(pt.is_numeric_dtype(df[c]) for c in cols)","tryCatchPattern":"try:\n    df.eval(expr)\nexcept TypeError as e:\n    if 'unsupported operand type' in str(e):\n        df.eval(expr, engine='python')  # python engine is more permissive\n    else:\n        raise","preventionTips":["Cast object/string columns to numeric with pd.to_numeric before arithmetic eval.","Inspect df.dtypes before passing column expressions to eval.","Fall back to engine='python' for mixed/object dtype arithmetic."],"tags":["pandas","eval","dtype","numexpr","type-mismatch"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}