apache/beam · error · TypeCheckError

All functions for a Combine PTransform must accept a single…

Error message

All functions for a Combine PTransform must accept a single argument compatible with: Iterable[Any]. Instead a function with input type: %s was received.

What it means

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.

Solutions

  1. Change the input hint to an iterable type, e.g. def f(xs: Iterable[int]) -> int.
  2. If the function truly processes a single element, use beam.Map instead of beam.Combine.
  3. Use beam.core.CombineFn (with create_accumulator/add_input/merge_accumulators/extract_output) when full control is needed.
  4. 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]).
  5. Example fix: `def f(xs: Iterable[int]) -> int: return sum(xs)` instead of `def f(x: int) -> int`.

Example fix

// before
def my_combine(x: int) -> int:
    return x + 1
pcoll | beam.Combine(my_combine)
// after
def my_combine(xs: Iterable[int]) -> int:
    return sum(xs)
pcoll | beam.Combine(my_combine)
Defensive patterns

Strategy: type-guard

Validate before calling

import apache_beam.typehints as t
hint = typing.get_type_hints(fn).get(first_param_name)
if hint is None or not is_consistent_with(hint, t.Iterable[t.Any]):
    raise TypeError('combine fn input must be Iterable[Any]-compatible')

Type guard

def takes_iterable(fn) -> bool:
    sig = inspect.signature(fn)
    p = next(iter(sig.parameters.values()))
    return p.annotation is not p.empty

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/761a32573517067c. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/transforms/core.py:1347

  def extract_output(self, accumulator, *args, **kwargs):
    return self._fn(accumulator, *args, **kwargs)

  def default_type_hints(self):
    fn_type_hints = typehints.decorators.IOTypeHints.from_callable(self._fn)
    type_hints = get_type_hints(self._fn).with_defaults(fn_type_hints)
    if type_hints.input_types is None:
      return type_hints
    else:
      # fn(Iterable[V]) -> V becomes CombineFn(V) -> V
      input_args, input_kwargs = type_hints.input_types
      if not input_args:
        if len(input_kwargs) == 1:
          input_args, input_kwargs = tuple(input_kwargs.values()), {}
        else:
          raise TypeError('Combiner input type must be specified positionally.')
      if not is_consistent_with(input_args[0],
                                typehints.Iterable[typehints.Any]):
        raise TypeCheckError(
            'All functions for a Combine PTransform must accept a '
            'single argument compatible with: Iterable[Any]. '
            'Instead a function with input type: %s was received.' %
            input_args[0])
      input_args = (element_type(input_args[0]), ) + input_args[1:]
      # TODO(robertwb): Assert output type is consistent with input type?
      return type_hints.with_input_types(*input_args, **input_kwargs)

  def infer_output_type(self, input_type):
    return _strip_output_annotations(
        trivial_inference.infer_return_type(self._fn, [input_type]))

  def for_input_type(self, input_type):
    # Avoid circular imports.
    from apache_beam.transforms import cy_combiners
    if self._fn is any:
      return cy_combiners.AnyCombineFn()
    elif self._fn is all:

View on GitHub (pinned to 12126d8942)