{"record":{"id":"95fae4e89aa7da7d","repo":"pathwaycom/pathway","slug":"cannot-use-expression-as-boolean","errorCode":null,"errorMessage":"Cannot use expression as boolean.","messagePattern":"Cannot use expression as boolean\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/expression.py","lineNumber":96,"sourceCode":"\n    @property\n    def _table(self) -> Table:\n        return self.to_column_expression()._table\n\n    @property\n    def _column(self) -> Column:\n        return self.to_column_expression()._column\n\n\nclass ColumnExpression(OperatorInput, ABC):\n    _dtype: dt.DType\n    _trace: Trace\n\n    def __init__(self):\n        self._trace = Trace.from_traceback()\n\n    def __bool__(self):\n        raise RuntimeError(\"Cannot use expression as boolean.\")\n\n    @property\n    @abstractmethod\n    def _deps(self) -> tuple[ColumnExpression, ...]: ...\n\n    @abstractmethod\n    def _to_internal(self) -> InternalColExpr: ...\n\n    def __repr__(self):\n        from pathway.internals.expression_printer import ExpressionFormatter\n\n        return ExpressionFormatter().eval_expression(self)\n\n    @staticmethod\n    def _wrap(\n        arg: ColumnExpression | Value | tuple[ColumnExpression, ...]\n    ) -> ColumnExpression:\n        if isinstance(arg, tuple):","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/expression.py#L78-L114","documentation":"ColumnExpression overrides __bool__ to raise RuntimeError because a Pathway expression is a deferred computation, not a value — Python's if/and/or/not would evaluate it immediately and almost always produce wrong results. The loud failure prevents silently using Python boolean semantics instead of building the vectorized & | ~ expression Pathway needs.","triggerScenarios":"Writing `if pw.this.x:` or `if table.col > 5:`; combining conditions with `and`/`or`/`not` (e.g. `pw.this.a > 1 and pw.this.b < 2`) inside filter/select; using `expr1 or expr2` to provide a default; ternary `x if cond else y` with an expression condition.","commonSituations":"Translating pandas boolean masks (`df[(df.a) & (df.b)]` authors forget & needs parentheses); reusing plain-python condition logic in UDF wrappers; debugging with `if expression:` in a notebook.","solutions":["Replace and/or/not with bitwise operators on expressions, each operand parenthesized: `(pw.this.a > 1) & (pw.this.b < 2)`, `~pw.this.flag`","Use pw.if_else / .if_else(condition, then, else) instead of python ternaries","If you truly need a per-row python branch, move the logic inside a UDF (@pw.udf) where values are materialized"],"exampleFix":"// before\ntable.filter(pw.this.a > 1 and pw.this.b < 2)\n// after\ntable.filter((pw.this.a > 1) & (pw.this.b < 2))","handlingStrategy":"validation","validationCode":null,"typeGuard":"from pathway.internals.expression import ColumnExpression\n\ndef is_column_expression(x) -> bool:\n    return isinstance(x, ColumnExpression)  # if true: never use it in if/and/or","tryCatchPattern":null,"preventionTips":["Always use &, |, ~ with parentheses on Pathway expressions","Use pw.if_else for branching instead of python ternaries on expressions","Search your Pathway code for ' and ' / ' or ' near pw.this as a lint habit"],"tags":["pathway","expression","boolean-operator","api-misuse","vectorization"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}