{"record":{"id":"330bc035385a9667","repo":"apache/beam","slug":"received-type-result-name-from-dofn-that-was-expected-to","errorCode":null,"errorMessage":"Received {type(result).__name__} from DoFn that was expected to produce a batch.","messagePattern":"Received (.+?) from DoFn that was expected to produce a batch\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/common.py","lineNumber":1848,"sourceCode":"\n    if tag is None:\n      self.main_receivers.receive(windowed_value)\n    else:\n      self.tagged_receivers[tag].receive(windowed_value)\n\n  def _write_batch_to_tag(self, tag, windowed_batch, watermark_estimator):\n    if watermark_estimator is not None:\n      for timestamp in windowed_batch.timestamps:\n        watermark_estimator.observe_timestamp(timestamp)\n\n    if tag is None:\n      self.main_receivers.receive_batch(windowed_batch)\n    else:\n      self.tagged_receivers[tag].receive_batch(windowed_batch)\n\n  def _verify_batch_output(self, result):\n    if isinstance(result, (WindowedValue, TimestampedValue)):\n      raise TypeError(\n          f\"Received {type(result).__name__} from DoFn that was \"\n          \"expected to produce a batch.\")\n\n  def start_bundle_outputs(self, results):\n    \"\"\"Validate that start_bundle does not output any elements\"\"\"\n    if results is None:\n      return\n    raise RuntimeError(\n        'Start Bundle should not output any elements but got %s' % results)\n\n  def finish_bundle_outputs(self, results):\n    \"\"\"Dispatch the result of finish_bundle to the appropriate receivers.\n\n    A value wrapped in a TaggedOutput object will be unwrapped and\n    then dispatched to the appropriate indexed output.\n    \"\"\"\n    if results is None:\n      return","sourceCodeStart":1830,"sourceCodeEnd":1866,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/common.py#L1830-L1866","documentation":"Beam's batched-DoFn path (_verify_batch_output) expects the process_batch method to return a plain batch (e.g. a list/ndarray of elements), not a WindowedValue or TimestampedValue. Receiving one means the DoFn mixed the per-element output protocol with the batch output protocol, so Beam raises TypeError.","triggerScenarios":"A DoFn implementing RunInBatchDoFn/process_batch returns WindowedValue(...) or TimestampedValue(...) instead of a raw batch container; or a batched DoFn reuses code from a standard element-wise DoFn that wraps outputs.","commonSituations":"Migrating an existing per-element DoFn to batched processing while keeping windowing wrappers around results; copy-pasting output construction from the standard DoFn path.","solutions":["Return the raw batch (list/array of values) from process_batch without wrapping in WindowedValue or TimestampedValue.","Move windowing/timestamp handling out of the batched DoFn; the runner applies windowing at the receiver level.","If per-element timestamps are needed, use the standard (non-batched) process() path instead."],"exampleFix":"// before\ndef process_batch(self, batch):\n    return [WindowedValue(x, timestamp, window) for x in batch]\n// after\ndef process_batch(self, batch):\n    return [x * 2 for x in batch]  # plain batch, no WindowedValue wrapper","handlingStrategy":"type-guard","validationCode":"def _assert_raw_batch(result):\n    assert not isinstance(result, (WindowedValue, TimestampedValue)), 'process_batch must return a raw batch'","typeGuard":"def is_raw_batch(r):\n    return not isinstance(r, (WindowedValue, TimestampedValue))","tryCatchPattern":"try:\n    batch_out = fn.process_batch(batch)\nexcept TypeError as e:\n    if 'expected to produce a batch' in str(e):\n        raise ValueError('Unwrap WindowedValue/TimestampedValue in process_batch return') from e\n    raise","preventionTips":["Keep batched DoFns free of WindowedValue/TimestampedValue wrappers; let the runner handle windowing.","Write a unit test asserting process_batch returns a plain container type.","Do not copy output code from element-wise DoFns into batched ones."],"tags":["python","apache-beam","batched-dofn","type-error"],"backgroundTag":"incompatible-return-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"}