{"record":{"id":"37610dceb96a81ef","repo":"apache/beam","slug":"combine-fn-must-be-provided","errorCode":null,"errorMessage":"combine_fn must be provided","messagePattern":"combine_fn must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/userstate.py","lineNumber":143,"sourceCode":"    Args:\n      name (str): The name by which the state is identified.\n      coder (Coder): Coder specifying how to encode the values to be combined.\n        May be inferred.\n      combine_fn (``CombineFn`` or ``callable``): Function specifying how to\n        combine the values passed to state.\n    \"\"\"\n    # Avoid circular import.\n    from apache_beam.transforms.core import CombineFn\n\n    # We want the coder to be optional, but unfortunately it comes\n    # before the non-optional combine_fn parameter, which we can't\n    # change for backwards compatibility reasons.\n    #\n    # Instead, allow it to be omitted (by either passing two arguments\n    # or combine_fn by keyword.)\n    if combine_fn is None:\n      if coder is None:\n        raise ValueError('combine_fn must be provided')\n      else:\n        coder, combine_fn = None, coder\n    self.combine_fn = CombineFn.maybe_from_callable(combine_fn)\n    # The coder here should be for the accumulator type of the given CombineFn.\n    if coder is None:\n      coder = self.combine_fn.get_accumulator_coder()\n\n    super().__init__(name, coder)\n\n  def to_runner_api(\n      self, context: 'PipelineContext') -> beam_runner_api_pb2.StateSpec:\n    return beam_runner_api_pb2.StateSpec(\n        combining_spec=beam_runner_api_pb2.CombiningStateSpec(\n            combine_fn=self.combine_fn.to_runner_api(context),\n            accumulator_coder_id=context.coders.get_id(self.coder)),\n        protocol=beam_runner_api_pb2.FunctionSpec(\n            urn=common_urns.user_state.BAG.urn))\n","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/userstate.py#L125-L161","documentation":"CombiningValueStateSpec's constructor historically accepted (name, combine_fn) positionally; to stay backward compatible it now requires combine_fn either as the second positional argument or via the combine_fn keyword. If combine_fn is None and coder is also None, there is no way to derive the accumulation logic, so a ValueError is raised.","triggerScenarios":"Calling CombiningValueStateSpec('name') with neither a second positional argument nor combine_fn=...; passing combine_fn=None explicitly while also omitting coder.","commonSituations":"Migrating code that previously passed (name, coder, combine_fn) and dropping the wrong argument; writing CombiningValueStateSpec(name, None) intending to fill it in later.","solutions":["Provide the combine_fn: CombiningValueStateSpec('name', sum) or CombiningValueStateSpec('name', combine_fn=sum)","If you intended the second argument as coder, use the combine_fn= keyword to make intent explicit","Use a callable or CombineFn instance (CombineFn.maybe_from_callable accepts both)"],"exampleFix":"// before\nspec = CombiningValueStateSpec('sum')\n// after\nspec = CombiningValueStateSpec('sum', combine_fn=sum)","handlingStrategy":"validation","validationCode":"assert combine_fn is not None, 'CombiningValueStateSpec requires combine_fn'\nspec = CombiningValueStateSpec('name', combine_fn=combine_fn)","typeGuard":null,"tryCatchPattern":"try:\n    spec = CombiningValueStateSpec('name', combine_fn=combine_fn)\nexcept ValueError as e:\n    raise ConfigError(f'combine_fn missing for state: {e}') from e","preventionTips":["Always pass combine_fn by keyword to make the call unambiguous","Use a callable (sum, min, max) or a CombineFn subclass","Review signature changes when upgrading Beam — the legacy positional form changed"],"tags":["python","apache-beam","userstate","combining-value","missing-argument"],"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"}