apache/beam · error · ValueError

Use () not .

Error message

Use %s() not %s.

What it means

Beam's PTransform.__init__ rejects a PTransform class object passed instead of an instance. Class objects are deliberately not treated as callables, so passing e.g. Map instead of Map() raises ValueError immediately. The intent is that transforms must be instantiated before being applied to a pipeline.

Solutions

  1. Add parentheses and required arguments: use `beam.Map(...)` with a callable or an already-instantiated DoFn instead of the bare class.
  2. If you meant to pass a DoFn class to ParDo, instantiate it first: `beam.ParDo(MyDoFn(args))`.
  3. Check the exact failing expression in the traceback; the class name in the message is the object you passed without constructing it.

Example fix

// before
result = beam.Map
// after
result = beam.Map(lambda x: x * 2)
Defensive patterns

Strategy: validation

Validate before calling

def ensure_transform_instance(t):
  import inspect
  if inspect.isclass(t):
    raise TypeError(f'Pass an instance: {t.__name__}(...), not the class')
  return t

Type guard

def is_ptransform_instance(t):
  from apache_beam.transforms.ptransform import PTransform
  return isinstance(t, PTransform) and not isinstance(t, type)

Prevention

When it happens

Trigger: Constructing a PTransform subclass instance whose `fn` argument is itself a PTransform class (not an instance), e.g. `p | Map` or `ParDo(MapFn)` where MapFn is a class object and the outer transform wraps classes via `fn.__name__`.

Common situations: Forgetting parentheses on a transform (`beam.Map` instead of `beam.Map(lambda x: x)`); passing a DoFn class to a wrapper expecting an instance; older tutorials or snippets using class-passing style that Beam no longer accepts.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/transforms/ptransform.py:881


class PTransformWithSideInputs(PTransform):
  """A superclass for any :class:`PTransform` (e.g.
  :func:`~apache_beam.transforms.core.FlatMap` or
  :class:`~apache_beam.transforms.core.CombineFn`)
  invoking user code.

  :class:`PTransform` s like :func:`~apache_beam.transforms.core.FlatMap`
  invoke user-supplied code in some kind of package (e.g. a
  :class:`~apache_beam.transforms.core.DoFn`) and optionally provide arguments
  and side inputs to that code. This internal-use-only class contains common
  functionality for :class:`PTransform` s that fit this model.
  """
  def __init__(self, fn, *args, **kwargs):
    # type: (WithTypeHints, *Any, **Any) -> None
    if isinstance(fn, type) and issubclass(fn, WithTypeHints):
      # Don't treat Fn class objects as callables.
      raise ValueError('Use %s() not %s.' % (fn.__name__, fn.__name__))
    self.fn = self.make_fn(fn, bool(args or kwargs))
    # Now that we figure out the label, initialize the super-class.
    super().__init__()

    if (any(isinstance(v, pvalue.PCollection) for v in args) or
        any(isinstance(v, pvalue.PCollection) for v in kwargs.values())):
      raise error.SideInputError(
          'PCollection used directly as side input argument. Specify '
          'AsIter(pcollection) or AsSingleton(pcollection) to indicate how the '
          'PCollection is to be used.')
    self.args, self.kwargs, self.side_inputs = util.remove_objects_from_args(
        args, kwargs, pvalue.AsSideInput)
    self.raw_side_inputs = args, kwargs

    # Prevent name collisions with fns of the form '<function <lambda> at ...>'
    self._cached_fn = self.fn

    # Ensure fn and side inputs are picklable for remote execution.

View on GitHub (pinned to 12126d8942)