{"record":{"id":"235b98922199a55c","repo":"pathwaycom/pathway","slug":"left-part-of-a-join-condition-has-to-be-a-referenc","errorCode":null,"errorMessage":"Left part of a join condition has to be a reference to a table on the left side of a join","messagePattern":"Left part of a join condition has to be a reference to a table on the left side of a join","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/joins.py","lineNumber":1159,"sourceCode":"    try:\n        eval_type(cond)\n    except TypeError:\n        raise TypeError(\n            \"Incompatible types in a join condition.\\n\"\n            + f\"The types are: {eval_type(cond._left)} and {eval_type(cond._right)}. \"\n            + \"You might try casting the respective columns to Any type to circumvent this,\"\n            + \" but this is most probably an error.\"\n        )\n    cond_left = cast(expr.ColumnReference, cond._left)\n    cond_right = cast(expr.ColumnReference, cond._right)\n    if cond_left.table == right and cond_right.table == left:\n        raise ValueError(\n            \"The boolean condition is not properly ordered.\\n\"\n            + \"The left part should refer to left joinable and the right one should refer to the right joinable,\"\n            + \" e.g. t1.join(t2, t1.bar==t2.foo).\"\n        )\n    if cond_left.table != left:\n        raise ValueError(\n            \"Left part of a join condition has to be a reference to a table \"\n            + \"on the left side of a join\"\n        )\n    if cond_right.table != right:\n        raise ValueError(\n            \"Right part of a join condition has to be a reference to a table \"\n            + \"on the right side of a join\"\n        )\n    return cond_left, cond_right, cond\n\n\ndef join(\n    left: Joinable,\n    right: Joinable,\n    *on: expr.ColumnExpression,\n    id: expr.ColumnReference | None = None,\n    how: JoinMode = JoinMode.INNER,\n    left_instance: expr.ColumnReference | None = None,","sourceCodeStart":1141,"sourceCodeEnd":1177,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/joins.py#L1141-L1177","documentation":"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.","triggerScenarios":"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.","commonSituations":"Joining two of several tables and referencing the wrong variable; conditions built earlier and reused across different join calls.","solutions":["Make the left operand reference the left joinable: t1.join(t2, t1.k == t2.k)","If a third table is genuinely needed, join it in a separate step and then join the result"],"exampleFix":"# before\nres = t1.join(t2, t3.k == t2.k)\n\n# after\nres = t1.join(t2, t1.k == t2.k)","handlingStrategy":"validation","validationCode":"def left_ref_ok(left, cond) -> bool:\n    return cond._left.table == left\n\nassert left_ref_ok(t1, t1.k == t2.k)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reference only the two join arguments inside the condition; bring third tables in via chained joins","Re-check condition variables after renaming tables in a pipeline"],"tags":["pathway","join","condition","api-misuse"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}