pathwaycom/pathway · error · TypeError

Cannot perform pathway.coalesce on columns of types {[dtype.

Error message

Cannot perform pathway.coalesce on columns of types {[dtype.typehint for dtype in dtypes]}.

What it means

Raised when pw.coalesce produces a least-common-ancestor of Any while at least one argument is not Any. This means the dtypes could not be meaningfully unified (the LCA collapsed to Any), which Pathway treats as an error rather than silently returning an untyped column; the message lists the typehints of all arguments.

Source

Thrown at python/pathway/internals/type_interpreter.py:398

        self._check_for_disallowed_types("pathway.coalesce", *dtypes)
        ret_type = dtypes[0]
        non_optional_arg = False
        for dtype in dtypes:
            try:
                ret_type = dt.types_lca(dtype, ret_type, raising=True)
            except TypeError:
                raise TypeError(
                    "Incompatible types in for a coalesce expression.\n"
                    + f"The types are: {dtypes}. "
                    + "You might try casting the expressions to Any type to circumvent this, "
                    + "but this is most probably an error."
                )
            if not isinstance(dtype, dt.Optional):
                # FIXME: do we want to be more radical and return now?
                # Maybe with a warning that some args are skipped?
                non_optional_arg = True
        if ret_type is dt.ANY and any(dtype is not dt.ANY for dtype in dtypes):
            raise TypeError(
                f"Cannot perform pathway.coalesce on columns of types {[dtype.typehint for dtype in dtypes]}."
            )
        ret_type = dt.unoptionalize(ret_type) if non_optional_arg else ret_type
        return _wrap(expression, ret_type)

    def eval_require(
        self,
        expression: expr.RequireExpression,
        state: TypeInterpreterState | None = None,
        **kwargs,
    ) -> expr.RequireExpression:
        assert state is not None
        args = [
            self.eval_expression(arg, state=state, **kwargs) for arg in expression._args
        ]
        arg_dtypes = [arg._dtype for arg in args]
        new_state = state.with_new_col(
            [arg for arg in expression._args if isinstance(arg, expr.ColumnReference)]

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Cast the heterogeneous argument to the concrete type first (e.g. pw.this.json_col.astype(str)) so the LCA becomes concrete
  2. Restructure so fallback columns share the dtype of the primary column (fix source schemas)
  3. Use a chain of pw.if_else/is_not_none if the columns genuinely have different types and different semantics
  4. As a last resort, cast all arguments to Any — accepting loss of type checking

Example fix

# before
v = pw.coalesce(pw.this.int_col, pw.this.json_col)  # LCA collapses to Any

# after
v = pw.coalesce(pw.this.int_col, pw.this.json_col.astype(int))
Defensive patterns

Strategy: type-guard

Validate before calling

import pathway as pw

def coalesce_lca_is_concrete(dtypes) -> bool:
    try:
        ret = dtypes[0]
        for d in dtypes[1:]:
            ret = pw.typehints.lca(d, ret)
        return ret is not None and not ret.equivalent_to(pw.typehints.Any())
    except TypeError:
        return False

Type guard

def lca_not_any(*dtypes) -> bool:
    import pathway as pw
    try:
        ret = dtypes[0]
        for d in dtypes[1:]:
            ret = pw.typehints.lca(d, ret)
        return not ret.equivalent_to(pw.typehints.Any())
    except TypeError:
        return False

Try / catch

try:
    v = pw.coalesce(*cols)
except TypeError:
    v = pw.coalesce(*[c.astype(target) for c in cols])

Prevention

When it happens

Trigger: pw.coalesce over columns whose only common ancestor is Any, e.g. an int column with a Json column, or a DateTime with a list column; mixing Json with concrete scalars; tuples of different shapes.

Common situations: Coalescing a parsed column with a raw Json fallback; merging heterogeneous columns from different sources under the assumption they are the same; Optional columns of unrelated payload types.

Related errors


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