{"record":{"id":"248d8dfc2e11aa67","repo":"pathwaycom/pathway","slug":"incompatible-types-in-a-join-condition-the-types","errorCode":null,"errorMessage":"Incompatible types in a join condition.\nThe 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.","messagePattern":"Incompatible types in a join condition\\.\nThe types are: (.+?) and (.+?)\\. You might try casting the respective columns to Any type to circumvent this, but this is most probably an error\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/joins.py","lineNumber":1144,"sourceCode":"        not isinstance(cond, expr.ColumnBinaryOpExpression)\n        or cond._operator != op.eq\n        or not isinstance(cond._left, expr.ColumnReference)\n        or not isinstance(cond._right, expr.ColumnReference)\n    ):\n        raise ValueError(\n            \"join condition should be of form <left_table>.<column> == <right_table>.<column>\"\n        )\n    return cond\n\n\ndef validate_join_condition(\n    cond: expr.ColumnExpression, left: Table, right: Table\n) -> tuple[expr.ColumnReference, expr.ColumnReference, expr.ColumnBinaryOpExpression]:\n    cond = validate_shape(cond)\n    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        )","sourceCodeStart":1126,"sourceCodeEnd":1162,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/joins.py#L1126-L1162","documentation":"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.","triggerScenarios":"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.","commonSituations":"Schemas drifting between systems (int keys in one table, stringified keys in another); joining on pw.this.id against an externally sourced string column.","solutions":["Align the column types upstream: apply t2 = t2.with_columns(key=pw.cast(int, t2.key)) or astype before joining","Fix the schema so both join columns share a comparable type","Only if you are certain the data is actually comparable: cast both sides to pw.Any as the message suggests"],"exampleFix":"# before\nres = t1.join(t2, t1.user_id == t2.user_id)  # int vs str\n\n# after\nt2 = t2.with_columns(user_id=pw.cast(int, t2.user_id))\nres = t1.join(t2, t1.user_id == t2.user_id)","handlingStrategy":"validation","validationCode":"from pathway.internals.type_interpreter import eval_type\n\ndef types_comparable(l_ref, r_ref) -> bool:\n    try:\n        eval_type(l_ref == r_ref)\n        return True\n    except TypeError:\n        return False\n\nassert types_comparable(t1.k, t2.k), \"cast columns to a common type before joining\"","typeGuard":null,"tryCatchPattern":"try:\n    t1.join(t2, t1.k == t2.k)\nexcept TypeError as e:\n    if \"Incompatible types in a join condition\" in str(e):\n        raise TypeError(f\"align key types then retry: {e}\") from e\n    raise","preventionTips":["Define shared pw.Schema classes for key columns across tables","Cast keys (pw.cast) at ingestion time so joins never see mixed types"],"tags":["pathway","join","types","type-mismatch","api-misuse"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}