{"record":{"id":"8f39e92be1889dc1","repo":"apache/beam","slug":"process-batch-method-on-self-fn-r-does-not-have-an-input","errorCode":null,"errorMessage":"process_batch method on {self.fn!r} does not have an input type annoation","messagePattern":"process_batch method on (.+?) does not have an input type annoation","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":1717,"sourceCode":"      return self\n    else:\n      return self.with_exception_handling(\n          error_handler=error_handler, **exception_handling_kwargs)\n\n  def default_type_hints(self):\n    return self.fn.get_type_hints()\n\n  def infer_output_type(self, input_type):\n    return self.fn.infer_output_type(input_type)\n\n  def infer_batch_converters(self, input_element_type):\n    # TODO: Test this code (in batch_dofn_test)\n    if self.fn._process_batch_defined:\n      input_batch_type = self.fn._get_input_batch_type_normalized(\n          input_element_type)\n\n      if input_batch_type is None:\n        raise TypeError(\n            \"process_batch method on {self.fn!r} does not have \"\n            \"an input type annoation\")\n\n      try:\n        # 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:","sourceCodeStart":1699,"sourceCodeEnd":1735,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L1699-L1735","documentation":" During batch DoFn setup, if a DoFn defines a process_batch method but its input batch type annotation cannot be resolved (returns None), Beam raises this TypeError. The annotation is required to build the element↔batch converter.","triggerScenarios":"Defining a DoFn with process_batch but omitting an input type annotation on it (or annotating in a way that normalizes to None), then using it in a ParDo that enables batch processing (e.g. with a runner/transform that calls _get_input_batch_type_normalized).","commonSituations":"Writing batch-optimized DoFns (e.g. for pandas/arrow) and forgetting type hints on process_batch; hints removed by wrappers/decorators; using older Beam versions where batch support annotations differ.","solutions":["Add a concrete input type annotation to process_batch, e.g. def process_batch(self, batch: np.ndarray).","Ensure annotations are preserved (avoid decorators that strip __annotations__).","Verify with DoFn._get_input_batch_type_normalized that the hint resolves to a batch type.","If batch processing is not intended, remove process_batch and use process instead.","Example fix: `def process_batch(self, batch: pandas.DataFrame)` instead of `def process_batch(self, batch)`."],"exampleFix":"// before\nclass MyDoFn(beam.DoFn):\n    def process_batch(self, batch):\n        yield batch.sum()\n// after\nclass MyDoFn(beam.DoFn):\n    def process_batch(self, batch: pandas.DataFrame):\n        yield batch.sum()","handlingStrategy":"validation","validationCode":"hints = typing.get_type_hints(MyDoFn.process_batch)\nif 'batch' not in hints or hints['batch'] is None:\n    raise TypeError('process_batch needs a concrete input type annotation')","typeGuard":"def process_batch_annotated(dofn_cls) -> bool:\n    return hasattr(dofn_cls, 'process_batch') and bool(get_type_hints(dofn_cls.process_batch).get('batch'))","tryCatchPattern":null,"preventionTips":["Always annotate process_batch parameters and returns fully.","Avoid decorators that strip __annotations__ from batch methods.","Test batch DoFns locally before running on a runner."],"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"}