pathwaycom/pathway · error · ValueError

Left part of a join condition has to be a reference to a tab

Error message

Left part of a join condition has to be a reference to a table on the left side of a join

What it means

The non-swapped left-side check in validate_join_condition: after ruling out the fully-swapped case, if cond_left.table != left the left operand references a table that is neither the left joinable (nor the special swapped pair), so ValueError 'Left part of a join condition has to be a reference to a table on the left side of a join' is raised. Typically means a third table's column crept into the condition.

Source

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

    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"
        )
    if cond_right.table != right:
        raise ValueError(
            "Right part of a join condition has to be a reference to a table "
            + "on the right side of a join"
        )
    return cond_left, cond_right, cond


def join(
    left: Joinable,
    right: Joinable,
    *on: expr.ColumnExpression,
    id: expr.ColumnReference | None = None,
    how: JoinMode = JoinMode.INNER,
    left_instance: expr.ColumnReference | None = None,

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Make the left operand reference the left joinable: t1.join(t2, t1.k == t2.k)
  2. If a third table is genuinely needed, join it in a separate step and then join the result

Example fix

# before
res = t1.join(t2, t3.k == t2.k)

# after
res = t1.join(t2, t1.k == t2.k)
Defensive patterns

Strategy: validation

Validate before calling

def left_ref_ok(left, cond) -> bool:
    return cond._left.table == left

assert left_ref_ok(t1, t1.k == t2.k)

Prevention

When it happens

Trigger: t1.join(t2, t3.k == t2.k) — left operand belongs to a different table t3; or after renames the variable no longer holds the table passed as left.

Common situations: Joining two of several tables and referencing the wrong variable; conditions built earlier and reused across different join calls.

Related errors


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