apache/beam · error · TypeError

Returning a %s from a ParDo or FlatMap is not allowed. Pleas

Error message

Returning a %s from a ParDo or FlatMap is not allowed. Please use list(%r) if you really want this behavior.

What it means

Apache Beam raises this TypeError from DoFnInvoker.handle_process_outputs when a user DoFn (ParDo/FlatMap) returns a str, bytes, or dict directly. Since these are iterable, Beam would otherwise silently treat them as a collection of outputs and iterate over them element by element, which is almost never what the user intended. The error forces you to make the intent explicit by wrapping the value in list(...).

Source

Thrown at sdks/python/apache_beam/runners/common.py:1697

  def handle_process_outputs(
      self, windowed_input_element, results, watermark_estimator=None):
    # type: (WindowedValue, Iterable[Any], Optional[WatermarkEstimator]) -> None

    """Dispatch the result of process computation to the appropriate receivers.

    A value wrapped in a TaggedOutput object will be unwrapped and
    then dispatched to the appropriate indexed output.
    """
    if self._check_user_dofn_output:
      # This bug is deterministic per DoFn: if process() returns a
      # str/bytes/dict once, it does so for every element. So we only need to
      # validate the first output and can then disable the check to avoid
      # per-element overhead (see
      # https://github.com/apache/beam/issues/18712).
      self._check_user_dofn_output = False
      if isinstance(results, (str, bytes, dict)):
        object_type = type(results).__name__
        raise TypeError(
            'Returning a %s from a ParDo or FlatMap is not allowed. '
            'Please use list(%r) if you really want this behavior.' %
            (object_type, results))

    if results is None:
      results = []

    # TODO(https://github.com/apache/beam/issues/20404): Verify that the
    #  results object is a valid iterable type if
    #  performance_runtime_type_check is active, without harming performance
    output_element_count = 0
    for result in results:
      tag, result = self._handle_tagged_output(result)

      if not self._process_yields_batches:
        # process yields elements
        windowed_value = self._maybe_propagate_windowing_info(
            windowed_input_element, result)

View on GitHub (pinned to 12126d8942)

Solutions

  1. Wrap the value in a list: `return [my_string]` / `return list(my_dict.items())` / `return [my_dict]` depending on whether the value should be one element or many.
  2. Use `yield` instead of `return` so each element is emitted individually.
  3. If you really want the str/bytes/dict iterated, make it explicit with `list(result)` as the message suggests.

Example fix

// before
class ParseJson(beam.DoFn):
    def process(self, element):
        return json.loads(element)  # returns dict -> TypeError
// after
class ParseJson(beam.DoFn):
    def process(self, element):
        yield json.loads(element)  # or: return [json.loads(element)]
Defensive patterns

Strategy: type-guard

Validate before calling

def _is_valid_dofn_return(r):
    return r is None or isinstance(r, (list, tuple, set, frozenset)) or (hasattr(r, '__iter__') and not isinstance(r, (str, bytes, dict)))

Type guard

def is_iterable_of_outputs(r):
    return not isinstance(r, (str, bytes, dict)) and (r is None or hasattr(r, '__iter__'))

Try / catch

try:
    out = fn.process(elem)
except TypeError as e:
    if 'ParDo or FlatMap is not allowed' in str(e):
        out = list(fn.process(elem))
    else:
        raise

Prevention

When it happens

Trigger: A DoFn's process() method (used via ParDo, FlatMap, or Map wrappers) executes `return some_string`, `return some_bytes`, or `return some_dict` instead of returning a list/iterable of elements or yielding.

Common situations: Returning a dict thinking it will pass through as a single element; returning a parsed JSON string from process(); writing `return line.strip()` in a FlatMap over lines, which returns a str; confusion between yield (element) and return (iterable of elements) semantics in Beam DoFns.

Related errors


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