pathwaycom/pathway · error · TypeError
Cannot perform pathway.if_else on columns of types {then_dty
Error message
Cannot perform pathway.if_else on columns of types {then_dtype.typehint} and {else_dtype.typehint}. What it means
Raised when the then/else branches of pw.if_else have dtypes with no common ancestor: dt.types_lca(then, else, raising=True) throws and the interpreter converts it into a TypeError naming both typehints. Both branches must unify to one result dtype.
Source
Thrown at python/pathway/internals/type_interpreter.py:481
)
else:
then_ = self.eval_expression(expression._then, state=state, **kwargs)
if isinstance(if_, expr.IsNoneExpression) and isinstance(
if_._expr, expr.ColumnReference
):
else_ = self.eval_expression(
expression._else, state=state.with_new_col([if_._expr], **kwargs)
)
else:
else_ = self.eval_expression(expression._else, state=state, **kwargs)
then_dtype = then_._dtype
else_dtype = else_._dtype
try:
lca = dt.types_lca(then_dtype, else_dtype, raising=True)
except TypeError:
raise TypeError(
f"Cannot perform pathway.if_else on columns of types {then_dtype.typehint} and {else_dtype.typehint}."
)
if lca is dt.ANY:
raise TypeError(
f"Cannot perform pathway.if_else on columns of types {then_dtype.typehint} and {else_dtype.typehint}."
)
expression = expr.IfElseExpression(if_, then_, else_)
return _wrap(expression, lca)
def eval_make_tuple(
self,
expression: expr.MakeTupleExpression,
state: TypeInterpreterState | None = None,
**kwargs,
) -> expr.MakeTupleExpression:
expression = super().eval_make_tuple(expression, state=state, **kwargs)
dtypes = tuple(arg._dtype for arg in expression._args)
self._check_for_disallowed_types("pathway.make_tuple", *dtypes)View on GitHub (pinned to fa2f74a464)
Solutions
- Cast both branches to a common type: pw.if_else(cond, pw.this.a.astype(str), pw.this.b.astype(str))
- Use matching literal types in both branches (e.g. None handled via Optional-aware expressions or equal-typed sentinels)
- Align source schemas so paired columns share dtype
- If mixing is deliberate, cast both to Any (documented escape hatch, loses checking)
Example fix
# before v = pw.if_else(pw.this.ok, pw.this.code, pw.this.label) # int vs str # after v = pw.if_else(pw.this.ok, pw.this.code.astype(str), pw.this.label)
Defensive patterns
Strategy: type-guard
Validate before calling
import pathway as pw
def branches_compatible(then_dtype, else_dtype) -> bool:
try:
lca = pw.typehints.lca(then_dtype, else_dtype)
return lca is not None and not lca.equivalent_to(pw.typehints.Any())
except TypeError:
return False Type guard
def branches_same_type(then_dtype, else_dtype) -> bool:
return then_dtype.equivalent_to(else_dtype) Try / catch
try:
v = pw.if_else(cond, x, y)
except TypeError:
v = pw.if_else(cond, x.astype(str), y.astype(str)) Prevention
- Keep then/else branch types identical by construction
- Use same-typed sentinels (0 / 0.0, "" / "") instead of mixing types
- Cast one branch when pairing columns from different schemas
When it happens
Trigger: pw.if_else(cond, pw.this.int_col, pw.this.str_col); branches of different literal types (1 vs "1"); one branch returning DateTime and the other None-untyped; branches whose LCA only exists for identical shapes of tuples/lists and those shapes differ.
Common situations: Returning type-inconsistent literals from branches (0 vs None vs ""); joining values from columns with divergent schemas; forgetting to cast one branch after a schema change.
Related errors
- Pathway does not support using unary operator {operator_fun.
- Pathway does not support using binary operator {operator.__n
- Cannot change type from {right} to {left}.\npw.`declare_type
- Incompatible types in for a coalesce expression.\nThe types
- First argument of pathway.if_else has to be bool, found {if_
AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15).
Data as JSON: /api/errors/c2a2043a9979f519.
Report an issue: GitHub.