apache/beam · error · TypeError

Map can be used only with callable objects. Received %r…

Error message

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

What it means

beam.Map accepts only plain callables; a DoFn instance or any other non-callable is rejected up front with this TypeError, since Map builds a lambda wrapper around fn rather than a ParDo-accepted DoFn.

Solutions

  1. Switch to beam.ParDo(MyDoFn(...)) if fn is a DoFn instance.
  2. Pass a callable: a lambda, function, method, or callable class instance.
  3. Verify you're not calling the function when passing it: beam.Map(my_fn) not beam.Map(my_fn(x)).
  4. Wrap the DoFn's process logic in a plain function if Map semantics are what you need.

Example fix

// before
beam.Map(MyDoFn())
// after
beam.ParDo(MyDoFn())
// or
beam.Map(lambda x: x * 2)
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: beam.Map(SomeDoFn()) or beam.Map(some_object) where fn does not implement __call__.

Common situations: Confusion between beam.Map and beam.ParDo when refactoring to stateful/DoFn-based transforms; passing a method result instead of the method; passing data (like a dict) intended as extra context rather than a function.

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/37ab3174c48992d6. Report an issue: GitHub.

Appendix: source

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

  single element.

  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:`Map` 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(
        'Map can be used only with callable objects. '
        'Received %r instead.' % (fn))
  from apache_beam.transforms.util import fn_takes_side_inputs
  if fn_takes_side_inputs(fn):
    wrapper = lambda x, *args, **kwargs: [fn(x, *args, **kwargs)]
  else:
    wrapper = lambda x: [fn(x)]

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

  # TODO. What about callable classes?
  if hasattr(fn, '__name__'):
    wrapper.__name__ = fn.__name__

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

View on GitHub (pinned to 12126d8942)