pathwaycom/pathway · error · TypeError

Pathway does not support using binary operator {expression._

Error message

Pathway does not support using binary operator {expression._operator.__name__} on columns of types {left_dtype}, {right_dtype}.It refers to the following expression:
{expression_info}

What it means

When lowering a binary operator expression (+, -, *, <, ==, ...) to an engine call, the evaluator looks up a handler for the (operator, left dtype, right dtype) triple — after unwrapping Optionals. If none is registered, it raises this TypeError with the operator and both dtypes. Normally the earlier TypeInterpreter catches this, so seeing it means static typing was bypassed (e.g. via pw.cast/declare or Any-typed intermediates).

Source

Thrown at python/pathway/internals/graph_runner/expression_evaluator.py:413

            )
        ) is not None:
            return result_expression

        left_dtype_unoptionalized, right_dtype_unoptionalized = dt.unoptionalize_pair(
            left_dtype,
            right_dtype,
        )

        if (
            dtype_and_handler := get_binary_operators_mapping_optionals(
                operator_fun, left_dtype_unoptionalized, right_dtype_unoptionalized
            )
        ) is not None:
            return dtype_and_handler[1](left, right)

        expression_info = get_expression_info(expression)
        # this path should be covered by TypeInterpreter
        raise TypeError(
            f"Pathway does not support using binary operator {expression._operator.__name__}"
            + f" on columns of types {left_dtype}, {right_dtype}."
            + "It refers to the following expression:\n"
            + expression_info
        )

    def eval_const(
        self,
        expression: expr.ColumnConstExpression,
        eval_state: RowwiseEvalState | None = None,
    ):
        return api.Expression.const(expression._val, expression._dtype.to_engine())

    def eval_call(
        self,
        expression: expr.ColumnCallExpression,
        eval_state: RowwiseEvalState | None = None,
    ):

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Match the dtypes named in the message: cast one side explicitly (pw.this.a.cast(int)) or fix the schema so both operands are types the operator supports
  2. For Json/Any columns, first extract and convert to a concrete dtype (pw.Json[...] accessors, .astype-like selects) before applying the operator
  3. Wrap risky combinations in pw.if_else/t.try_else so incompatible rows degrade gracefully instead of failing the pipeline

Example fix

// before
result = pw.this.quantity * pw.this.price  # price is pw.Json / Any
// after
result = pw.this.quantity * pw.this.price.as_float()
Defensive patterns

Strategy: type-guard

Type guard

SUPPORTED_ADD = {(int, int), (int, float), (float, float), (str, str)}

def binary_op_supported(op, left_dtype, right_dtype) -> bool:
    return (type(left_dtype), type(right_dtype)) in SUPPORTED_ADD or str(left_dtype) == str(right_dtype) == 'ANY' is False

Try / catch

try:
    table.select(s=pw.this.a * pw.this.b)
except TypeError as e:
    if "does not support using binary operator" in str(e):
        # add explicit casts / converters for the named dtypes and rebuild
        ...

Prevention

When it happens

Trigger: Adding str + int columns; comparing a DateTimeNaive with a DateTimeUtc; arithmetic on Json/Any-typed columns whose real runtime dtypes have no handler; mixing bytes and str; operations between Pointer and int after casting away types.

Common situations: Columns left as pw.Json or Any from dynamic sources, then used in arithmetic; casts that lie about the true dtype; schema drift where a column silently changed type; datetime arithmetic mixing naive and UTC columns.

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/bf11f56c4c13a99f. Report an issue: GitHub.