apache/beam · error · TypeError

MapTuple can be used only with callable objects. Received…

Error message

MapTuple can be used only with callable objects. Received %r instead.

What it means

beam.MapTuple unpacks tuple elements into fn's positional parameters, so fn must be a callable accepting multiple positional args. A non-callable (typically a DoFn instance) raises this TypeError before any wrapping occurs.

Solutions

  1. Use beam.ParDo for DoFn instances.
  2. Pass a function-style callable like beam.MapTuple(lambda k, v: ...).
  3. Confirm the object exposes __call__ if you intend a callable class instance.
  4. If the DoFn's process signature unpacks tuples, extract a plain function equivalent for MapTuple usage.

Example fix

// before
beam.MapTuple(MyDoFn())
// after
beam.MapTuple(lambda k, v: (k, v * 2))
// or for DoFn:
beam.ParDo(MyDoFn())
Defensive patterns

Strategy: type-guard

Validate before calling

if not callable(fn):
    raise TypeError('MapTuple needs a callable, got %r' % (fn,))

Type guard

def is_maptuple_fn(fn):
    return callable(fn) and not isinstance(fn, DoFn)

Try / catch

try:
    out = pcoll | beam.MapTuple(fn)
except TypeError as e:
    if 'callable objects' in str(e):
        out = pcoll | beam.ParDo(fn)
    else:
        raise

Prevention

When it happens

Trigger: beam.MapTuple(SomeDoFn()) or beam.MapTuple(non_callable) where fn lacks __call__.

Common situations: Confusing MapTuple with ParDo when processing KV/grouped PCollections; refactoring Map to MapTuple and accidentally passing a DoFn; copy-paste between Map/FlatMap/MapTuple call sites.

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/20325c9066075653. Report an issue: GitHub.

Appendix: source

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

  (e.g. key-value pairs).

  Args:
    fn (callable): a callable object.
    *args: positional arguments passed to the transform callable.
    **kwargs: keyword arguments passed to the transform callable.

  Returns:
    ~apache_beam.pvalue.PCollection:
    A :class:`~apache_beam.pvalue.PCollection` containing the
    :func:`MapTuple` outputs.

  Raises:
    TypeError: If the **fn** passed as argument is not a callable.
      Typical error is to pass a :class:`DoFn` instance which is supported only
      for :class:`ParDo`.
  """
  if not callable(fn):
    raise TypeError(
        'MapTuple can be used only with callable objects. '
        'Received %r instead.' % (fn))

  label = 'MapTuple(%s)' % ptransform.label_from_callable(fn)

  arg_names, defaults = get_function_args_defaults(fn)
  num_defaults = len(defaults)
  if num_defaults < len(args) + len(kwargs):
    raise TypeError('Side inputs must have defaults for MapTuple.')

  if defaults or args or kwargs:
    wrapper = lambda x, *args, **kwargs: [fn(*(tuple(x) + args), **kwargs)]
  else:
    wrapper = lambda x: [fn(*x)]

  # Proxy the type-hint information from the original function to this new
  # wrapped function.
  type_hints = get_type_hints(fn).with_defaults(

View on GitHub (pinned to 12126d8942)