{"record":{"id":"8c2e9696830fac5f","repo":"apache/beam","slug":"process-batch-method-on-self-fn-r-does-not-have-a-return","errorCode":null,"errorMessage":"process_batch method on {self.fn!r} does not have a return type annoation","messagePattern":"process_batch method on (.+?) does not have a return type annoation","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":1740,"sourceCode":"        # Generate a batch converter to convert between the input type and the\n        # (batch) input type of process_batch\n        self.fn.input_batch_converter = BatchConverter.from_typehints(\n            element_type=input_element_type, batch_type=input_batch_type)\n      except TypeError as e:\n        raise TypeError(\n            \"Failed to find a BatchConverter for the input types of DoFn \"\n            f\"{self.fn!r} (element_type={input_element_type!r}, \"\n            f\"batch_type={input_batch_type!r}).\") from e\n\n    else:\n      self.fn.input_batch_converter = None\n\n    if self.fn._can_yield_batches:\n      output_batch_type = self.fn._get_output_batch_type_normalized(\n          input_element_type)\n      if output_batch_type is None:\n        # TODO: Mention process method in this error\n        raise TypeError(\n            f\"process_batch method on {self.fn!r} does not have \"\n            \"a return type annoation\")\n\n      # Generate a batch converter to convert between the output type and the\n      # (batch) output type of process_batch\n      output_element_type = self.infer_output_type(input_element_type)\n\n      try:\n        self.fn.output_batch_converter = BatchConverter.from_typehints(\n            element_type=output_element_type, batch_type=output_batch_type)\n      except TypeError as e:\n        raise TypeError(\n            \"Failed to find a BatchConverter for the *output* types of DoFn \"\n            f\"{self.fn!r} (element_type={output_element_type!r}, \"\n            f\"batch_type={output_batch_type!r}). Maybe you need to override \"\n            \"DoFn.infer_output_type to set the output element type?\") from e\n    else:\n      self.fn.output_batch_converter = None","sourceCodeStart":1722,"sourceCodeEnd":1758,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L1722-L1758","documentation":" If a DoFn can yield batches (_can_yield_batches) but its process_batch return type annotation cannot be normalized to a batch type (None), Beam raises this TypeError, since it must know the output batch type to build the output converter.","triggerScenarios":"Defining a batch-yielding DoFn whose process_batch lacks a return type annotation (or whose annotation normalizes to None), then running it through a batch-enabled ParDo which calls _get_output_batch_type_normalized.","commonSituations":"Forgetting `-> Iterable[...]` / `-> Iterator[np.ndarray]` style return hints on process_batch; decorators stripping annotations; writing process (not batch) docs but yielding batches inadvertently.","solutions":["Add a return type annotation to process_batch, e.g. def process_batch(self, b: np.ndarray) -> Iterator[np.ndarray].","Ensure the annotation resolves to a concrete batch type (not a bare Iterator without element type).","Avoid annotation-stripping decorators; re-add typing info if wrapped.","If batches are not intended, remove batch-yield logic and use plain process.","Example fix: `def process_batch(self, batch: np.ndarray) -> Iterator[np.ndarray]` instead of no return annotation."],"exampleFix":"// before\nclass MyDoFn(beam.DoFn):\n    def process_batch(self, batch: np.ndarray):\n        yield batch * 2\n// after\nclass MyDoFn(beam.DoFn):\n    def process_batch(self, batch: np.ndarray) -> Iterator[np.ndarray]:\n        yield batch * 2","handlingStrategy":"validation","validationCode":"hints = typing.get_type_hints(MyDoFn.process_batch)\nif 'return' not in hints:\n    raise TypeError('process_batch needs a return type annotation')","typeGuard":"def process_batch_return_annotated(dofn_cls) -> bool:\n    return 'return' in get_type_hints(dofn_cls.process_batch)","tryCatchPattern":null,"preventionTips":["Always annotate process_batch return types like Iterator[np.ndarray].","Include element types in Iterator/Iterable annotations, not bare forms.","Run a small local pipeline test to surface annotation problems before deployment."],"tags":["python","apache-beam","batchdofn","type-hints"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}