apache/beam · error · TypeCheckError

Returning a from a ParDo or FlatMap is discouraged. Please…

Error message

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

What it means

Beam's _check_type rejects a DoFn/FlatMap callable returning a dict, bytes, or str directly. Iterating such a return value would yield keys/characters rather than records, which is almost always a bug, so Beam raises TypeCheckError to force the user to be explicit.

Solutions

  1. Wrap the value in a list: return [my_string] / [my_dict].
  2. Convert to a generator: yield the value instead of returning it.
  3. If you truly want per-character/key iteration, use list(value) as the message suggests.
  4. Use beam.Map instead of FlatMap when emitting exactly one element per input.

Example fix

// before
def expand(x):
    return x['payload']  # a str
// after
def expand(x):
    return [x['payload']]
Defensive patterns

Strategy: validation

Validate before calling

def safe_flatmap(fn):
    def wrapped(x):
        out = fn(x)
        if isinstance(out, (str, bytes, dict)):
            return [out]
        return out
    return wrapped

Type guard

def returns_element_list(out) -> bool:
    return out is None or (isinstance(out, list) and not isinstance(out, (str, bytes, dict)))

Try / catch

try:
    out = fn(x)
except TypeCheckError as e:
    log.error('FlatMap returned bad value: %s', e)
    return []

Prevention

When it happens

Trigger: A FlatMap/ParDo function returns a string, bytes, or dict (e.g. 'return s' instead of yielding, or returning a dict expecting it to be one record).

Common situations: Returning a JSON string from a FlatMap intending a single element; returning a dict as one output record; accidentally returning input unchanged when input is a string.

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

Appendix: source

Thrown at sdks/python/apache_beam/typehints/typecheck.py:113

      result = method(*args, **kwargs)
    except TypeCheckError as e:
      # TODO(BEAM-10710): Remove the 'ParDo' prefix for the label name
      error_msg = (
          'Runtime type violation detected within ParDo(%s): '
          '%s' % (self.full_label, e))
      _, _, tb = sys.exc_info()
      raise TypeCheckError(error_msg).with_traceback(tb)
    else:
      return self._check_type(result)

  @staticmethod
  def _check_type(output):
    if output is None:
      return output

    elif isinstance(output, (dict, bytes, str)):
      object_type = type(output).__name__
      raise TypeCheckError(
          'Returning a %s from a ParDo or FlatMap is '
          'discouraged. Please use list("%s") if you really '
          'want this behavior.' % (object_type, output))
    elif not isinstance(output, abc.Iterable):
      raise TypeCheckError(
          'FlatMap and ParDo must return an '
          'iterable. %s was returned instead.' % type(output))
    return output


class TypeCheckWrapperDoFn(AbstractDoFnWrapper):
  """A wrapper around a DoFn which performs type-checking of input and output.
  """
  def __init__(self, dofn, type_hints, label=None):
    super().__init__(dofn)
    self._process_fn = self.dofn._process_argspec_fn()
    if type_hints.input_types:
      input_args, input_kwargs = type_hints.input_types

View on GitHub (pinned to 12126d8942)