apache/beam · error · TypeError

Expected a CombineFn or callable, got %r

Error message

Expected a CombineFn or callable, got %r

What it means

apache_beam.transforms.core.CombineFn.maybe_from_callable raises this TypeError when given a value that is neither a CombineFn instance nor a callable. The library requires a combiner with a defined reduce strategy; anything else cannot be turned into a CombineFn.

Source

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

      input_type: the type of input elements.
    """
    return self

  @staticmethod
  def from_callable(fn):
    return CallableWrapperCombineFn(fn)

  @staticmethod
  def maybe_from_callable(fn, has_side_inputs=True):
    # type: (typing.Union[CombineFn, typing.Callable], bool) -> CombineFn
    if isinstance(fn, CombineFn):
      return fn
    elif callable(fn) and not has_side_inputs:
      return NoSideInputsCallableWrapperCombineFn(fn)
    elif callable(fn):
      return CallableWrapperCombineFn(fn)
    else:
      raise TypeError('Expected a CombineFn or callable, got %r' % fn)

  def get_accumulator_coder(self):
    return coders.registry.get_coder(object)

  urns.RunnerApiFn.register_pickle_urn(python_urns.PICKLED_COMBINE_FN)


class _ReiterableChain(object):
  """Like itertools.chain, but allowing re-iteration."""
  def __init__(self, iterables):
    self.iterables = iterables

  def __iter__(self):
    for iterable in self.iterables:
      for item in iterable:
        yield item

  def __bool__(self):

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass a callable (e.g. a function or lambda) or a CombineFn instance to maybe_from_callable / Combine().
  2. Print and inspect the value being passed; if it is None, fix the upstream code that was supposed to produce the function.
  3. If passing a class, instantiate it first (MyCombineFn() not MyCombineFn).
  4. Wrap a simple aggregation in a lambda or def so it is callable, e.g. lambda xs: sum(xs).

Example fix

// before
beam.Combine(maybe_combiner)  # maybe_combiner is None
// after
if not (isinstance(maybe_combiner, CombineFn) or callable(maybe_combiner)):
    raise ValueError(f'bad combiner: {maybe_combiner!r}')
p = pcoll | beam.Combine(maybe_combiner or (lambda xs: sum(xs)))
Defensive patterns

Strategy: validation

Validate before calling

if not (isinstance(fn, CombineFn) or callable(fn)):
    raise TypeError(f'combiner must be CombineFn or callable, got {fn!r}')

Type guard

def is_combine_fn(x) -> bool:
    return isinstance(x, CombineFn) or callable(x)

Prevention

When it happens

Trigger: Calling CombineFn.maybe_from_callable(x) (directly or via CombineGlyph / Combine PTransform wiring) with None, a string, a class (not instance), or another non-callable object.

Common situations: Passing the wrong variable (e.g. None from a failed factory function or an unset config) as the combine function; passing a class object like `sum` vs a proper callable; refactoring that renamed a combiner function so the name now binds to something else.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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