{"record":{"id":"8124b36df010e402","repo":"apache/beam","slug":"typehint-is-not-of-nullable-type-and-cannot-be-converted-to","errorCode":null,"errorMessage":"Typehint is not of nullable type, and cannot be converted to a NullableCoder","messagePattern":"Typehint is not of nullable type, and cannot be converted to a NullableCoder","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/coders/coders.py","lineNumber":606,"sourceCode":"\n  def _create_impl(self):\n    return coder_impl.NullableCoderImpl(self._value_coder.get_impl())\n\n  def to_type_hint(self):\n    return typehints.Optional[self._value_coder.to_type_hint()]\n\n  def _get_component_coders(self):\n    # type: () -> List[Coder]\n    return [self._value_coder]\n\n  @classmethod\n  def from_type_hint(cls, typehint, registry):\n    if typehints.is_nullable(typehint):\n      return cls(\n          registry.get_coder(\n              typehints.get_concrete_type_from_nullable(typehint)))\n    else:\n      raise TypeError(\n          'Typehint is not of nullable type, '\n          'and cannot be converted to a NullableCoder',\n          typehint)\n\n  def is_deterministic(self):\n    # type: () -> bool\n    return self._value_coder.is_deterministic()\n\n  def as_deterministic_coder(self, step_label, error_message=None):\n    if self.is_deterministic():\n      return self\n    else:\n      deterministic_value_coder = self._value_coder.as_deterministic_coder(\n          step_label, error_message)\n      return NullableCoder(deterministic_value_coder)\n\n  def __eq__(self, other):\n    return (","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/coders/coders.py#L588-L624","documentation":"NullableCoder.from_type_hint() builds a NullableCoder that wraps the coder for the inner type, but only accepts type hints recognized as nullable by apache_beam.typehints. If the typehint is not a nullable type (e.g. Optional[...] was not used or a plain type was passed), the constructor path cannot proceed and a TypeError is raised.","triggerScenarios":"Calling NullableCoder.from_type_hint(typehint, registry) with a typehint for which typehints.is_nullable() returns False, e.g. a bare int/str hint or a non-Optional generic.","commonSituations":"Pipelines where a PTransform's output type was inferred as non-nullable but the coder registry still attempts to build a NullableCoder; usually a symptom of a type-hint mismatch between the pipeline graph and registered coders.","solutions":["Check that the typehint passed to from_type_hint is actually a nullable type such as Optional[T] or typehints.Nullable[T]","Use typehints.get_concrete_type_from_nullable to inspect what inner type would be extracted and confirm the hint shape","If the value cannot be None, register a plain coder for the concrete type instead of NullableCoder","Trace where the typehint originates (PDone/DoFn annotations) and fix the annotation to Optional[...]"],"exampleFix":"// before\nNullableCoder.from_type_hint(int, registry)\n// after\nNullableCoder.from_type_hint(Optional[int], registry)","handlingStrategy":"type-guard","validationCode":"from apache_beam.typehints import typehints\nif typehints.is_nullable(typehint):\n    coder = NullableCoder.from_type_hint(typehint, registry)","typeGuard":"def is_nullable_hint(th) -> bool:\n    from apache_beam.typehints import typehints\n    return typehints.is_nullable(th)","tryCatchPattern":"try:\n    coder = NullableCoder.from_type_hint(typehint, registry)\nexcept TypeError as e:\n    coder = registry.get_coder(typehints.get_concrete_type(typehint))","preventionTips":["Annotate optional values as Optional[T] in DoFn type hints","Check typehints.is_nullable before choosing NullableCoder","Prefer registry.get_coder and let Beam pick the coder class"],"tags":["python","type-system","coders","apache-beam"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}