{"record":{"id":"2eb65be7cd0da207","repo":"pathwaycom/pathway","slug":"pathway-does-not-support-using-unary-operator-ope","errorCode":null,"errorMessage":"Pathway does not support using unary operator {operator_fun.__name__} on column of type {expression._expr._dtype.typehint}.\\nIt refers to the following expression:\\n{expression_info}","messagePattern":"Pathway does not support using unary operator (.+?) on column of type (.+?)\\.\\\\nIt refers to the following expression:\\\\n(.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/type_interpreter.py","lineNumber":92,"sourceCode":"        if state.check_colref_to_unoptionalize_from_colrefs(expression):\n            return dt.unoptionalize(dtype)\n        return dtype\n\n    def eval_unary_op(\n        self,\n        expression: expr.ColumnUnaryOpExpression,\n        state: TypeInterpreterState | None = None,\n        **kwargs,\n    ) -> expr.ColumnUnaryOpExpression:\n        expression = super().eval_unary_op(expression, state=state, **kwargs)\n        operand_dtype = expression._expr._dtype\n        operator_fun = expression._operator\n        if (\n            dtype := get_unary_operators_mapping(operator_fun, operand_dtype)\n        ) is not None:\n            return _wrap(expression, dtype)\n        expression_info = get_expression_info(expression)\n        raise TypeError(\n            f\"Pathway does not support using unary operator {operator_fun.__name__}\"\n            + f\" on column of type {expression._expr._dtype.typehint}.\\n\"\n            + \"It refers to the following expression:\\n\"\n            + expression_info\n        )\n\n    def eval_binary_op(\n        self,\n        expression: expr.ColumnBinaryOpExpression,\n        state: TypeInterpreterState | None = None,\n        **kwargs,\n    ) -> expr.ColumnBinaryOpExpression:\n        expression = super().eval_binary_op(expression, state=state, **kwargs)\n        left_dtype = expression._left._dtype\n        right_dtype = expression._right._dtype\n        return _wrap(\n            expression,\n            self._eval_binary_op(","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/type_interpreter.py#L74-L110","documentation":"Raised by the type interpreter when a unary operator (e.g. ~, -, +) is applied to a column whose dtype has no mapping for that operator. Pathway type-checks expressions eagerly; since unary operators are only defined for specific dtypes (mostly numbers and bools), applying one to e.g. a str or Json column fails at graph-construction time with the operator name, the column type, and a trace of the offending expression.","triggerScenarios":"pw.this.flag.apply(lambda x: ~x) style is fine for bools, but -pw.this.name on a str column, ~pw.this.value on an int/float (bitwise not unsupported for floats), or applying unary minus to an Optional/Json column triggers it; also via overloaded operators inside select/with_columns.","commonSituations":"Porting pandas/SQL expressions where unary minus or bitwise not works on more types (e.g. - on strings coerces, ~ works on any truthy); Optional[int] columns where the operator must be applied after unwrap; JSON columns needing explicit cast before arithmetic.","solutions":["Cast the column to a supported type first: pw.this.col.astype(int) (or pw.cast_to) before the operator","For Optional columns, handle the None case explicitly with pw.if_else(pw.this.col.is_not_none(), -pw.this.col, None) or unwrap after a default","Replace bitwise ~ on non-bool columns with pw.this.col != True or a comparison appropriate to the type","Do the transformation in .apply() with Python semantics if Pathway-level typing is too strict"],"exampleFix":"# before\ntable = table.select(value=-pw.this.name)  # str does not support unary '-'\n\n# after\ntable = table.select(value=-pw.this.amount)  # numeric column\n# or\ntable = table.select(value=pw.this.name.apply(lambda s: -s))","handlingStrategy":"type-guard","validationCode":"import pathway as pw\n\ndef unary_op_supported(dtype, op: str) -> bool:\n    numeric = dtype in (pw.typehints.Int(), pw.typehints.Float())\n    if op in (\"neg\", \"pos\", \"invert\"):\n        return numeric or (op == \"invert\" and dtype == pw.typehints.Bool())\n    return False\n\n# check before applying: unary_op_supported(pw.typehints.Float(), \"neg\")","typeGuard":"def can_negate(dtype) -> bool:\n    import pathway as pw\n    th = dtype\n    return th.equivalent_to(pw.typehints.Float()) or th.equivalent_to(pw.typehints.Int())","tryCatchPattern":"try:\n    out = t.select(v=-pw.this.col)\nexcept TypeError:\n    out = t.select(v=pw.this.col.astype(float).apply(lambda x: -x))","preventionTips":["Fix dtypes in input schemas instead of relying on inference","Cast with astype before operators on heterogeneous or Optional columns","Run a tiny pw.debug.compute_and_print on a sample to surface type errors early"],"tags":["pathway","type-checking","unary-operator","dtype","typeerror"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}