pathwaycom/pathway · error · TypeError

Cannot change type from {right} to {left}.\nTable.update_typ

Error message

Cannot change type from {right} to {left}.\nTable.update_types() should be used only for type narrowing or type extending.

What it means

Raised by Table.update_types() when the new type is neither a subtype nor a supertype of the current type for some column — i.e. the change is not a narrowing or widening. update_types only re-labels type hints without conversion, so unrelated types (e.g. int -> str) are rejected as would break the type lattice.

Source

Thrown at python/pathway/internals/table.py:2247

    @trace_user_frame
    @check_arg_types
    def update_types(self, **kwargs: Any) -> Table:
        """Updates types in schema. Has no effect on the runtime."""

        for name in kwargs.keys():
            if name not in self.keys():
                raise ValueError(
                    "Table.update_types() argument name has to be an existing table column name."
                )
        new_schema = self.schema.with_types(**kwargs)
        for name in kwargs.keys():
            left = new_schema._dtypes()[name]
            right = self.schema._dtypes()[name]
            if not (
                dt.dtype_issubclass(left, right) or dt.dtype_issubclass(right, left)
            ):
                raise TypeError(
                    f"Cannot change type from {right} to {left}.\n"
                    + "Table.update_types() should be used only for type narrowing or type extending."
                )
        return self._with_schema(new_schema)

    @trace_user_frame
    @check_arg_types
    def update_id_type(self, id_type, *, id_append_only: bool | None = None) -> Table:
        id_type = dt.wrap(id_type)
        assert isinstance(id_type, dt.Pointer)
        return self._with_schema(
            self.schema.with_id_type(id_type, append_only=id_append_only)
        )

    @check_arg_types
    def cast_to_types(self, **kwargs: Any) -> Table:
        """Casts columns to types."""

View on GitHub (pinned to fa2f74a464)

Solutions

  1. To convert values, use cast_to_types (or pw.this.col.cast(...)) instead of update_types
  2. To only re-hint within the hierarchy, pick a related type (subtype for narrowing, supertype for widening), e.g. int -> Any is allowed
  3. Check the current dtype first: print(t.schema._dtypes()) or t.eval_type(pw.this.col)
  4. If ids are involved, use update_id_type for Pointer types

Example fix

# before
t2 = t.update_types(age=str)  # int -> str: not narrowing/widening -> TypeError

# after (actual conversion)
t2 = t.cast_to_types(age=str)
# or a pure hint widening
t2 = t.update_types(age=Any)
Defensive patterns

Strategy: type-guard

Validate before calling

from pathway.internals import dtype as dt

def hint_compatible(old, new) -> bool:
    old, new = dt.wrap(old), dt.wrap(new)
    return dt.dtype_issubclass(new, old) or dt.dtype_issubclass(old, new)

Type guard

def is_narrowing_or_widening(t, col, new_type) -> bool:
    from pathway.internals import dtype as dt
    left, right = dt.wrap(new_type), t.schema._dtypes()[col]
    return dt.dtype_issubclass(left, right) or dt.dtype_issubclass(right, left)

Try / catch

try:
    t2 = t.update_types(col=str)
except TypeError as e:
    if 'should be used only for type narrowing' in str(e):
        t2 = t.cast_to_types(col=str)

Prevention

When it happens

Trigger: t.update_types(col=str) when col is currently int; changing Pointer[int] to Pointer[str]; changing a column to a type with no subtype/supertype relation to the current one.

Common situations: Trying to 'convert' data with update_types instead of actually casting values; connector schema changed the declared type between environments; narrowing too aggressively after a widening elsewhere.

Related errors


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