{"record":{"id":"0b6c0426b8dd2797","repo":"apache/beam","slug":"failed-to-find-a-batchconverter-for-the-output-types-of-dofn","errorCode":null,"errorMessage":"Failed to find a BatchConverter for the *output* types of DoFn {self.fn!r} (element_type={output_element_type!r}, batch_type={output_batch_type!r}). Maybe you need to override DoFn.infer_output_type to set the output element type?","messagePattern":"Failed to find a BatchConverter for the \\*output\\* types of DoFn (.+?) \\(element_type=(.+?), batch_type=(.+?)\\)\\. Maybe you need to override DoFn\\.infer_output_type to set the output element type\\?","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":1752,"sourceCode":"\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\n\n  def make_fn(self, fn, has_side_inputs):\n    if isinstance(fn, DoFn):\n      return fn\n    return CallableWrapperDoFn(fn)\n\n  def _process_argspec_fn(self):\n    return self.fn._process_argspec_fn()\n\n  def display_data(self):\n    return {\n        'fn': DisplayDataItem(self.fn.__class__, label='Transform Function'),","sourceCodeStart":1734,"sourceCodeEnd":1770,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L1734-L1770","documentation":" When the DoFn's output batch type is known, Beam builds an output BatchConverter from (output_element_type, output_batch_type). If no converter exists for that pair, the TypeError is re-raised with this message, hinting that infer_output_type may need overriding.","triggerScenarios":"Batch-yielding DoFn whose output element type (from infer_output_type, often defaulting to Any or an unsupported type) paired with the declared batch type has no registered BatchConverter.","commonSituations":"Custom element classes with pandas/arrow batch outputs; forgetting to override DoFn.infer_output_type so element type defaults incorrectly; missing optional deps (pandas/pyarrow) so no converter is registered.","solutions":["Override DoFn.infer_output_type to return a concrete supported element type (e.g. np.int64, a registered row type).","Register a custom BatchConverter for the (element_type, batch_type) pair.","Change the process_batch return annotation to a supported batch type (np.ndarray, pandas.DataFrame, pa.Table).","Install pandas/pyarrow if the intended converter requires them.","Example fix: override infer_output_type to return numpy.int64 so the output converter can be created."],"exampleFix":"// before\nclass MyDoFn(beam.DoFn):\n    def process_batch(self, batch: np.ndarray) -> Iterator[np.ndarray]: ...\n// after\nclass MyDoFn(beam.DoFn):\n    def infer_output_type(self, input_element_type):\n        return np.int64\n    def process_batch(self, batch: np.ndarray) -> Iterator[np.ndarray]: ...","handlingStrategy":"validation","validationCode":"out_t = MyDoFn().infer_output_type(el_t)\ntry:\n    BatchConverter.from_typehints(element_type=out_t, batch_type=out_batch_t)\nexcept TypeError:\n    raise TypeError('override infer_output_type with a supported element type')","typeGuard":"def output_converter_exists(dofn, el_t) -> bool:\n    try:\n        BatchConverter.from_typehints(\n            element_type=dofn.infer_output_type(el_t),\n            batch_type=get_output_batch_type(dofn))\n        return True\n    except TypeError:\n        return False","tryCatchPattern":"try:\n    run_batch_pipeline()\nexcept TypeError as e:\n    if 'output' in str(e) and 'BatchConverter' in str(e):\n        fix_infer_output_type(); run_batch_pipeline()\n    else:\n        raise","preventionTips":["Override DoFn.infer_output_type whenever outputs are batches of non-Any elements.","Keep output element and batch types aligned with registered converters.","Ensure pandas/pyarrow are installed for DataFrame/Table batch outputs."],"tags":["python","apache-beam","batchconverter","type-hints"],"backgroundTag":"incompatible-source-type","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"}