{"record":{"id":"761a32573517067c","repo":"apache/beam","slug":"all-functions-for-a-combine-ptransform-must-accept-a-single","errorCode":null,"errorMessage":"All functions for a Combine PTransform must accept a single argument compatible with: Iterable[Any]. Instead a function with input type: %s was received.","messagePattern":"All functions for a Combine PTransform must accept a single argument compatible with: Iterable\\[Any\\]\\. Instead a function with input type: (.+?) was received\\.","errorType":"validation","errorClass":"TypeCheckError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/transforms/core.py","lineNumber":1347,"sourceCode":"  def extract_output(self, accumulator, *args, **kwargs):\n    return self._fn(accumulator, *args, **kwargs)\n\n  def default_type_hints(self):\n    fn_type_hints = typehints.decorators.IOTypeHints.from_callable(self._fn)\n    type_hints = get_type_hints(self._fn).with_defaults(fn_type_hints)\n    if type_hints.input_types is None:\n      return type_hints\n    else:\n      # fn(Iterable[V]) -> V becomes CombineFn(V) -> V\n      input_args, input_kwargs = type_hints.input_types\n      if not input_args:\n        if len(input_kwargs) == 1:\n          input_args, input_kwargs = tuple(input_kwargs.values()), {}\n        else:\n          raise TypeError('Combiner input type must be specified positionally.')\n      if not is_consistent_with(input_args[0],\n                                typehints.Iterable[typehints.Any]):\n        raise TypeCheckError(\n            'All functions for a Combine PTransform must accept a '\n            'single argument compatible with: Iterable[Any]. '\n            'Instead a function with input type: %s was received.' %\n            input_args[0])\n      input_args = (element_type(input_args[0]), ) + input_args[1:]\n      # TODO(robertwb): Assert output type is consistent with input type?\n      return type_hints.with_input_types(*input_args, **input_kwargs)\n\n  def infer_output_type(self, input_type):\n    return _strip_output_annotations(\n        trivial_inference.infer_return_type(self._fn, [input_type]))\n\n  def for_input_type(self, input_type):\n    # Avoid circular imports.\n    from apache_beam.transforms import cy_combiners\n    if self._fn is any:\n      return cy_combiners.AnyCombineFn()\n    elif self._fn is all:","sourceCodeStart":1329,"sourceCodeEnd":1365,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/transforms/core.py#L1329-L1365","documentation":" When a type-hinted callable is wrapped as a CombineFn, Beam checks that the first input type hint is consistent with Iterable[Any], because combine functions receive an iterable of elements. A hint incompatible with Iterable (e.g. int, str, a plain T) triggers this TypeCheckError.","triggerScenarios":"Calling beam.Combine / CombineFn.from_callable / CallableWrapperCombineFn with a function whose single input annotation is not Iterable-compatible, e.g. def f(x: int) -> int, or List[SomeNonIterable] usage mis-annotated as a single element rather than a sequence.","commonSituations":"Annotating the combine fn like a per-element map fn (int instead of List[int]); reusing a Map-style function as a Combine fn; hinting with a non-iterable custom type; auto-generated stubs with wrong signatures.","solutions":["Change the input hint to an iterable type, e.g. def f(xs: Iterable[int]) -> int.","If the function truly processes a single element, use beam.Map instead of beam.Combine.","Use beam.core.CombineFn (with create_accumulator/add_input/merge_accumulators/extract_output) when full control is needed.","Strip or fix the wrong annotation (e.g. remove `-> int` input misuse) and let Beam infer, or set hints explicitly with with_input_types(Iterable[int]).","Example fix: `def f(xs: Iterable[int]) -> int: return sum(xs)` instead of `def f(x: int) -> int`."],"exampleFix":"// before\ndef my_combine(x: int) -> int:\n    return x + 1\npcoll | beam.Combine(my_combine)\n// after\ndef my_combine(xs: Iterable[int]) -> int:\n    return sum(xs)\npcoll | beam.Combine(my_combine)","handlingStrategy":"type-guard","validationCode":"import apache_beam.typehints as t\nhint = typing.get_type_hints(fn).get(first_param_name)\nif hint is None or not is_consistent_with(hint, t.Iterable[t.Any]):\n    raise TypeError('combine fn input must be Iterable[Any]-compatible')","typeGuard":"def takes_iterable(fn) -> bool:\n    sig = inspect.signature(fn)\n    p = next(iter(sig.parameters.values()))\n    return p.annotation is not p.empty","tryCatchPattern":null,"preventionTips":["Use Map/FlatMap for single-element functions; reserve Combine for Iterable input.","Annotate combine fns as (Iterable[T]) -> T.","Write unit tests that construct the Combine transform to catch hint mismatches early."],"tags":["python","apache-beam","type-hints","iterable"],"backgroundTag":"type-mismatch","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"}