{"record":{"id":"86f3a72df2709aca","repo":"pathwaycom/pathway","slug":"pathway-doesn-t-support-casting-source-type-to","errorCode":null,"errorMessage":"Pathway doesn't support casting {source_type} to {target_type}.","messagePattern":"Pathway doesn't support casting (.+?) to (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/graph_runner/expression_evaluator.py","lineNumber":575,"sourceCode":"        target_type = expression._return_type\n        source_type = dt.normalize_pointers(source_type)\n        target_type = dt.normalize_pointers(target_type)\n\n        if (\n            dt.dtype_equivalence(target_type, source_type)\n            or dt.dtype_equivalence(dt.Optional(source_type), target_type)\n            or (source_type == dt.NONE and isinstance(target_type, dt.Optional))\n            or target_type == dt.ANY\n        ):\n            return arg  # then cast is noop\n        if (\n            result_expression := get_cast_operators_mapping(\n                arg, source_type, target_type\n            )\n        ) is not None:\n            return result_expression\n\n        raise TypeError(\n            f\"Pathway doesn't support casting {source_type} to {target_type}.\"\n        )\n\n    def eval_convert(\n        self,\n        expression: expr.ConvertExpression,\n        eval_state: RowwiseEvalState | None = None,\n    ):\n        expr = self.eval_expression(expression._expr, eval_state=eval_state)\n        default = self.eval_expression(expression._default, eval_state=eval_state)\n        unwrap = expression._unwrap\n        source_type = expression._expr._dtype\n        target_type = expression._return_type\n\n        if (\n            dt.dtype_equivalence(target_type, source_type)\n            or dt.dtype_equivalence(dt.Optional(source_type), target_type)\n            or (source_type == dt.NONE and isinstance(target_type, dt.Optional))","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/graph_runner/expression_evaluator.py#L557-L593","documentation":"The cast expression evaluator first tries cheap paths (no-op casts, equivalent dtypes, NONE into Optional, anything into Any), then consults the registered cast-operator mapping. If no cast handler exists between the source and target dtype, it raises this TypeError: Pathway simply does not support that conversion via .cast().","triggerScenarios":"pw.this.col.cast(str) where col is a Pointer or Json; casting Any/Json directly to a concrete dtype (unsupported — Json needs its own accessors); casting between unrelated types like bool->str, bytes->int; casting DateTimeNaive<->DateTimeUtc; casting to Optional-of-unsupported inner type.","commonSituations":"Assuming .cast() behaves like str()/int() in python and works between anything; coercing Json fields by casting instead of using Json accessors; cleaning up badly-typed connector schemas with blanket casts.","solutions":["For Json/Any sources use Json accessors or conversion expressions (pw.Json.as_int(), dt parsing helpers) instead of .cast()","Convert via an intermediate supported step: first cast to a compatible dtype that is registered (e.g. int->float), or format datetimes with dt methods rather than casting","Fix the schema at ingestion so the expensive cast is unnecessary; use Optional only where the engine supports the inner cast"],"exampleFix":"// before\nvalue = pw.this.payload.cast(int)  # payload is pw.Json\n// after\nvalue = pw.this.payload.as_int()","handlingStrategy":"type-guard","validationCode":"KNOWN_CASTS = {(int, float), (float, int), (str, str), (int, str), (float, str)}\n\ndef cast_supported(src, dst) -> bool:\n    return (src, dst) in KNOWN_CASTS","typeGuard":"def is_directly_castable(src_dtype, dst_dtype) -> bool:\n    # conservative check: only primitives of the same family or identical dtypes\n    return src_dtype == dst_dtype or {str(src_dtype), str(dst_dtype)} <= {'int', 'float'}","tryCatchPattern":"try:\n    pw.this.col.cast(target)\nexcept TypeError as e:\n    if \"support casting\" in str(e):\n        # fall back to a UDF conversion or Json accessor\n        ...","preventionTips":["Do not treat .cast() as python's int()/str(); use it only for registered pairs","Convert Json fields with accessors (as_int/as_float) instead of casting","Fix types at the schema/connector level so casts are rarely needed"],"tags":["pathway","cast","dtype","type-conversion","expression"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}