pathwaycom/pathway · error · TypeError

Cannot get from {Json | None}.

Error message

Cannot get from {Json | None}.

What it means

Raised when get()/indexing is applied to a column of type Optional(Json) (Json | None). Pathway cannot index into a value that may be None, so unlike the plain-Json case (which is supported), the optional-Json case is rejected outright; the None possibility must be eliminated first.

Source

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

    ) -> expr.GetExpression:
        expression = super().eval_get(expression, state=state, **kwargs)
        object_dtype = expression._object._dtype
        index_dtype = expression._index._dtype
        default_dtype = expression._default._dtype

        if object_dtype == dt.JSON:
            # json
            if not dt.dtype_issubclass(default_dtype, dt.Optional(dt.JSON)):
                raise TypeError(
                    f"Default must be of type {Json | None}, found {default_dtype.typehint}."
                )
            if not expression._check_if_exists or default_dtype == dt.JSON:
                return _wrap(expression, dt.JSON)
            else:
                return _wrap(expression, dt.Optional(dt.JSON))
        elif object_dtype.equivalent_to(dt.Optional(dt.JSON)):
            # optional json
            raise TypeError(f"Cannot get from {Json | None}.")
        else:
            # sequence
            if (
                not isinstance(object_dtype, (dt.Array, dt.Tuple, dt.List))
                and object_dtype != dt.ANY
            ):
                raise TypeError(
                    f"Object in {expression!r} has to be a JSON or sequence."
                )
            if index_dtype != dt.INT:
                raise TypeError(f"Index in {expression!r} has to be an int.")

            if isinstance(object_dtype, dt.Array):
                return _wrap(expression, object_dtype.strip_dimension())
            if object_dtype == dt.ANY:
                return _wrap(expression, dt.ANY)

            if isinstance(object_dtype, dt.List):

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Guard with a null check: pw.if_else(pw.this.col.is_not_none(), pw.this.col.get('key'), None)
  2. Remove the None possibility first: pw.coalesce(pw.this.col, pw.Json({})).get('key') or replace_none-style filling with a Json default
  3. Change the schema to non-optional pw.Json and let the connector supply empty objects, or use .apply(lambda d: (d or {}).get('key')) for full Python semantics

Example fix

# before
v = pw.this.maybe_json.get("key")  # column is Optional[pw.Json] -> TypeError

# after
v = pw.if_else(
    pw.this.maybe_json.is_not_none(),
    pw.this.maybe_json.get("key"),
    None,
)
Defensive patterns

Strategy: type-guard

Validate before calling

import pathway as pw

def get_safe(optional_json_ref, key: str):
    return pw.if_else(
        optional_json_ref.is_not_none(),
        optional_json_ref.get(key),
        None,
    )

Type guard

def is_non_optional_json(dtype) -> bool:
    import pathway as pw
    return dtype.equivalent_to(pw.typehints.Json())

Try / catch

try:
    v = pw.this.maybe_json.get("key")
except TypeError:
    v = pw.if_else(
        pw.this.maybe_json.is_not_none(),
        pw.this.maybe_json.get("key"),
        None,
    )

Prevention

When it happens

Trigger: pw.this.maybe_json.get('key') or pw.this.maybe_json['key'] where the column was declared as Optional[pw.Json] (e.g. json_col: pw.Json | None); columns typed Optional(Json) after outer joins or pw.coalesce with None; get on a field produced by an earlier get(..., optional=True).

Common situations: Schemas declaring json: pw.Json | None to model missing payloads; outer-join results where the JSON side is nullable; chaining gets where the first get returns Optional(Json) and the second get is applied directly.

Related errors


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