{"record":{"id":"ee45d8b1a83dfa1f","repo":"apache/beam","slug":"dofn-self-do-fn-r-uses-unsupported-dofn-param-elementparam","errorCode":null,"errorMessage":"DoFn {self.do_fn!r} uses unsupported DoFn param ElementParam.","messagePattern":"DoFn (.+?) uses unsupported DoFn param ElementParam\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/common.py","lineNumber":361,"sourceCode":"    # type: () -> None\n\n    \"\"\"Validate that none of the DoFnParameters are repeated in the function\n    \"\"\"\n    self._check_duplicate_dofn_params(self.process_method)\n\n  def _validate_process_batch(self):\n    # type: () -> None\n    self._check_duplicate_dofn_params(self.process_batch_method)\n\n    for d in self.process_batch_method.defaults:\n      if not isinstance(d, core._DoFnParam):\n        continue\n\n      # Helpful errors for params which will be supported in the future\n      if d == (core.DoFn.ElementParam):\n        # We currently assume we can just get the typehint from the first\n        # parameter. ElementParam breaks this assumption\n        raise NotImplementedError(\n            f\"DoFn {self.do_fn!r} uses unsupported DoFn param ElementParam.\")\n\n      if d in (core.DoFn.KeyParam, core.DoFn.StateParam, core.DoFn.TimerParam):\n        raise NotImplementedError(\n            f\"DoFn {self.do_fn!r} has unsupported per-key DoFn param {d}. \"\n            \"Per-key DoFn params are not yet supported for process_batch \"\n            \"(https://github.com/apache/beam/issues/21653).\")\n\n      # Fallback to catch anything not explicitly supported\n      if not d in (core.DoFn.WindowParam,\n                   core.DoFn.TimestampParam,\n                   core.DoFn.PaneInfoParam):\n        raise ValueError(\n            f\"DoFn {self.do_fn!r} has unsupported process_batch \"\n            f\"method parameter {d}\")\n\n  def _validate_bundle_method(self, method_wrapper):\n    \"\"\"Validate that none of the DoFnParameters are used in the function","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/common.py#L343-L379","documentation":"process_batch (the DoFn batch API) does not support the per-element DoFn.ElementParam because batch methods receive a whole element sequence; the typehint assumption of the first parameter would break. _validate_process_batch raises NotImplementedError when ElementParam is declared.","triggerScenarios":"A DoFn defining process_batch with a parameter defaulted to core.DoFn.ElementParam, validated during DoFnSignature/DoFnInvoker setup via _validate.","commonSituations":"Migrating a per-element process() to process_batch() without dropping ElementParam; writing a batch DoFn by analogy with per-key params.","solutions":["Remove the ElementParam; the batch method already receives the elements collection itself","Keep the DoFn as a regular process() if per-element access semantics are required","Access element content from the batch parameter (e.g. a list of elements) instead"],"exampleFix":"// before\ndef process_batch(self, els, el=DoFn.ElementParam):\n// after\ndef process_batch(self, els):\n  for el in els: ...","handlingStrategy":"fallback","validationCode":"import inspect\nfrom apache_beam.transforms.core import DoFn\nbad = [d for d in inspect.signature(MyDoFn.process_batch).values if d.default is DoFn.ElementParam]\nassert not bad","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember batch methods receive the element collection, not a single element","Avoid mixing per-element params with process_batch"],"tags":["python","apache-beam","process-batch"],"backgroundTag":"unsupported-operation","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"}