pathwaycom/pathway · error · TypeError

Unsupported type {input_type}, use pw.DURATION

Error message

Unsupported type {input_type}, use pw.DURATION

What it means

Pathway represents durations with its own Duration type, not Python's datetime.timedelta, so the dtype translator rejects datetime.timedelta explicitly. The engine needs a first-class Duration dtype to implement arithmetic between datetimes and durations; mapping timedelta silently would break type checking of those operations.

Source

Thrown at python/pathway/internals/dtype.py:745

        dims_args = typing.get_args(dims)
        if dims == typing.Any or (dims_args and dims_args[-1] is ...):
            # tuple[X, ...] shapes (used by NDArray on numpy >= 2.1) leave the
            # number of dimensions unspecified, same as the older Any shape
            return Array(n_dim=None, wrapped=wrap(wrapped))
        return Array(n_dim=len(dims_args), wrapped=wrap(wrapped))
    elif input_type == api.PyObjectWrapper:
        return ANY_PY_OBJECT_WRAPPER
    elif typing.get_origin(input_type) == api.PyObjectWrapper:
        (inner,) = typing.get_args(input_type)
        return PyObjectWrapper(inner)
    elif isinstance(input_type, type) and issubclass(input_type, Enum):
        return ANY
    elif input_type == datetime.datetime:
        raise TypeError(
            f"Unsupported type {input_type}, use pw.DATE_TIME_UTC or pw.DATE_TIME_NAIVE"
        )
    elif input_type == datetime.timedelta:
        raise TypeError(f"Unsupported type {input_type}, use pw.DURATION")
    elif typing.get_origin(input_type) == asyncio.Future:
        args = get_args(input_type)
        (arg,) = args
        return Future(wrap(arg))
    else:
        dtype = {
            int: INT,
            bool: BOOL,
            str: STR,
            float: FLOAT,
            datetime_types.Duration: DURATION,
            datetime_types.DateTimeNaive: DATE_TIME_NAIVE,
            datetime_types.DateTimeUtc: DATE_TIME_UTC,
            np.int32: INT,
            np.int64: INT,
            np.float32: FLOAT,
            np.float64: FLOAT,
            bytes: BYTES,

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Replace datetime.timedelta with pw.Duration (pw.DURATION) in the schema/annotation
  2. For UDF return types, annotate pw.Duration and convert inside the UDF (e.g. via pw.Duration.duration(...)) instead of returning raw timedelta
  3. If the column just holds arbitrary numeric intervals, consider int/float seconds plus a conversion step

Example fix

// before
import datetime
class Sessions(pw.Schema):
    length: datetime.timedelta
// after
class Sessions(pw.Schema):
    length: pw.Duration
Defensive patterns

Strategy: type-guard

Validate before calling

import datetime

def check_schema_annotations(fields: dict) -> None:
    for name, tp in fields.items():
        if tp is datetime.timedelta:
            raise TypeError(f"field '{name}': use pw.Duration, not datetime.timedelta")

Type guard

import datetime

def is_supported_pathway_type(tp) -> bool:
    return tp is not datetime.timedelta

Prevention

When it happens

Trigger: A schema field annotated dt.timedelta / datetime.timedelta; passing timedelta to a dtype-inference API (pw.schema_from_types, column dtypes in connectors) that funnels into the dtype wrapper.

Common situations: Modeling interval/elapsed-time columns with the stdlib type out of habit; reusing dataclass annotations as Pathway schemas; UDF return annotations using timedelta.

Related errors


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