pathwaycom/pathway · error · TypeError

Incompatible types in a join condition. The types are: {eval

Error message

Incompatible types in a join condition.
The types are: {eval_type(cond._left)} and {eval_type(cond._right)}. You might try casting the respective columns to Any type to circumvent this, but this is most probably an error.

What it means

After the shape check, validate_join_condition evaluates the type of the == expression with eval_type; a TypeError from type evaluation is re-raised as TypeError 'Incompatible types in a join condition' listing both side types. Joining on columns whose pathway types cannot be compared (e.g. int vs str, or pointer vs int) triggers it; the message notes casting to Any (pw.cast) as an escape hatch but flags it as probably an error.

Source

Thrown at python/pathway/internals/joins.py:1144

        not isinstance(cond, expr.ColumnBinaryOpExpression)
        or cond._operator != op.eq
        or not isinstance(cond._left, expr.ColumnReference)
        or not isinstance(cond._right, expr.ColumnReference)
    ):
        raise ValueError(
            "join condition should be of form <left_table>.<column> == <right_table>.<column>"
        )
    return cond


def validate_join_condition(
    cond: expr.ColumnExpression, left: Table, right: Table
) -> tuple[expr.ColumnReference, expr.ColumnReference, expr.ColumnBinaryOpExpression]:
    cond = validate_shape(cond)
    try:
        eval_type(cond)
    except TypeError:
        raise TypeError(
            "Incompatible types in a join condition.\n"
            + f"The types are: {eval_type(cond._left)} and {eval_type(cond._right)}. "
            + "You might try casting the respective columns to Any type to circumvent this,"
            + " but this is most probably an error."
        )
    cond_left = cast(expr.ColumnReference, cond._left)
    cond_right = cast(expr.ColumnReference, cond._right)
    if cond_left.table == right and cond_right.table == left:
        raise ValueError(
            "The boolean condition is not properly ordered.\n"
            + "The left part should refer to left joinable and the right one should refer to the right joinable,"
            + " e.g. t1.join(t2, t1.bar==t2.foo)."
        )
    if cond_left.table != left:
        raise ValueError(
            "Left part of a join condition has to be a reference to a table "
            + "on the left side of a join"
        )

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Align the column types upstream: apply t2 = t2.with_columns(key=pw.cast(int, t2.key)) or astype before joining
  2. Fix the schema so both join columns share a comparable type
  3. Only if you are certain the data is actually comparable: cast both sides to pw.Any as the message suggests

Example fix

# before
res = t1.join(t2, t1.user_id == t2.user_id)  # int vs str

# after
t2 = t2.with_columns(user_id=pw.cast(int, t2.user_id))
res = t1.join(t2, t1.user_id == t2.user_id)
Defensive patterns

Strategy: validation

Validate before calling

from pathway.internals.type_interpreter import eval_type

def types_comparable(l_ref, r_ref) -> bool:
    try:
        eval_type(l_ref == r_ref)
        return True
    except TypeError:
        return False

assert types_comparable(t1.k, t2.k), "cast columns to a common type before joining"

Try / catch

try:
    t1.join(t2, t1.k == t2.k)
except TypeError as e:
    if "Incompatible types in a join condition" in str(e):
        raise TypeError(f"align key types then retry: {e}") from e
    raise

Prevention

When it happens

Trigger: t1.join(t2, t1.user_id == t2.user_name) where one column is int and the other str; joining on an id (Pointer) column against a plain string key column.

Common situations: Schemas drifting between systems (int keys in one table, stringified keys in another); joining on pw.this.id against an externally sourced string column.

Related errors


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