{"record":{"id":"7f7e004c6f4d9a11","repo":"pathwaycom/pathway","slug":"pathway-does-not-support-using-binary-operator-op","errorCode":null,"errorMessage":"Pathway does not support using binary operator {operator.__name__} on columns of types {original_left.typehint}, {original_right.typehint}.\\nIt refers to the following expression:\\n{expression_info}","messagePattern":"Pathway does not support using binary operator (.+?) on columns of types (.+?), (.+?)\\.\\\\nIt refers to the following expression:\\\\n(.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/type_interpreter.py","lineNumber":151,"sourceCode":"            return dtype\n\n        left_dtype, right_dtype = dt.unoptionalize_pair(left_dtype, right_dtype)\n\n        if (\n            dtype_and_handler := get_binary_operators_mapping_optionals(\n                operator, left_dtype, right_dtype\n            )\n        ) is not None:\n            return dtype_and_handler[0]\n\n        maybe_dtype = self._eval_binary_op_on_tuples(\n            left_dtype, right_dtype, operator, expression\n        )\n        if maybe_dtype is not None:\n            return maybe_dtype\n\n        expression_info = get_expression_info(expression)\n        raise TypeError(\n            f\"Pathway does not support using binary operator {operator.__name__}\"\n            + f\" on columns of types {original_left.typehint}, {original_right.typehint}.\\n\"\n            + \"It refers to the following expression:\\n\"\n            + expression_info\n        )\n\n    def _eval_binary_op_on_tuples(\n        self,\n        left_dtype: dt.DType,\n        right_dtype: dt.DType,\n        operator: Any,\n        expression: expr.ColumnExpression,\n    ) -> dt.DType | None:\n        if (\n            isinstance(left_dtype, (dt.Tuple, dt.List))\n            and isinstance(right_dtype, (dt.Tuple, dt.List))\n            and operator in tuple_handling_operators\n        ):","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/type_interpreter.py#L133-L169","documentation":"Raised by the type interpreter when a binary operator (e.g. +, *, ==, &) is applied to column types for which Pathway defines no combined operation. The interpreter checks the left/right dtypes (including tuple/list element-wise rules); on failure it reports the operator, both original typehints, and the expression trace so the offending line can be located.","triggerScenarios":"pw.this.quantity * pw.this.label where one is int and the other str; comparing incompatible types like pw.this.date_col == pw.this.id with mixed types; arithmetic between str and int columns; mixing bool with int under operators Pathway does not map for that pair.","commonSituations":"CSV/JSON ingestion where everything arrives as str or Any and users do arithmetic immediately; comparing a DateTime column to a plain str literal; Optional columns combined with plain columns without unwrapping; pandas-to-Pathway ports relying on implicit coercion.","solutions":["Cast the operands to compatible types before the operation: pw.this.col.astype(float) + pw.this.other.astype(float)","Ensure connector dtypes are correct: declare proper types in the input Schema (int, float) instead of relying on inferred str","For Optional columns, apply unwrap or replace None defaults first so both sides have concrete dtypes","If the mix is intentional, cast both sides to Any (pw.cast_to(Any)) to defer typing — last resort as it removes safety"],"exampleFix":"# before\nresult = table.select(total=pw.this.price * pw.this.amount)  # str * int unsupported\n\n# after\nresult = table.select(total=pw.this.price.astype(float) * pw.this.amount.astype(int))","handlingStrategy":"type-guard","validationCode":"import pathway as pw\n\ndef dtypes_compatible(l, r) -> bool:\n    \"\"\"Cheap check: both numeric, both str, or equal types.\"\"\"\n    num = lambda t: t in (pw.typehints.Int(), pw.typehints.Float())\n    return (num(l) and num(r)) or l.equivalent_to(r)","typeGuard":"def both_numeric(l, r) -> bool:\n    import pathway as pw\n    num = lambda t: t in (pw.typehints.Int(), pw.typehints.Float())\n    return num(l) and num(r)","tryCatchPattern":"try:\n    out = t.select(v=pw.this.a * pw.this.b)\nexcept TypeError:\n    out = t.select(v=pw.this.a.astype(float) * pw.this.b.astype(float))","preventionTips":["Declare explicit types in every input Schema; never let numeric fields default to str","Cast operands with astype at the boundary right after ingestion","Validate sample rows (pw.debug.compute_and_print) before building large graphs"],"tags":["pathway","type-checking","binary-operator","dtype","typeerror"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}