apache/beam · error · TypeError

'elements must be a list of elements'

Error message

'elements must be a list of elements'

What it means

The Create/Inline transform (yaml_provider.py:901) accepts 'elements' only as an iterable that is not a dict or str — i.e. a real list/sequence of elements. Passing a dict (keys would silently be used) or a string (characters would be used) raises TypeError 'elements must be a list of elements'.

Solutions

  1. Wrap the value in a list: elements: [{a: 1}] for a single record.
  2. For multiple records provide a YAML list: elements: [{a: 1}, {a: 2}].
  3. If passing strings as data, wrap each in a list: ['hello'] not 'hello'.

Example fix

# before
- type: Create
  elements: {a: 1}
# after
- type: Create
  elements:
    - a: 1
Defensive patterns

Strategy: type-guard

Validate before calling

def validate_elements(elements):
    if not isinstance(elements, list) or isinstance(elements, (dict, str)):
        raise SystemExit('elements must be a list; wrap single values: [{a: 1}]')

Type guard

def is_element_list(x) -> bool:
    return isinstance(x, list) and not isinstance(x, (dict, str))

Try / catch

try:
    result = create_transform(pcoll, elements)
except TypeError as e:
    log.error('Inline Create elements malformed: %s', e)
    raise

Prevention

When it happens

Trigger: YAML inline create with elements: '{a: 1, b: 2}' (a mapping) or elements: 'hello' (a string); programmatically calling the transform with a dict or str.

Common situations: Wanting to create a single record and passing a dict directly instead of a one-element list; YAML quoting confusion turning an intended list into 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/0f001c03d3ce2305. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/yaml/yaml_provider.py:901

    will result in an output with two elements with a schema of
    Row(element=int, a=int) looking like:

        Row(element=1, a=None)
        Row(element=None, a=2)

    Args:
        elements: The set of elements that should belong to the PCollection.
            YAML/JSON-style mappings will be interpreted as Beam rows.
            Primitives will be mapped to rows with a single "element" field.
        reshuffle: (optional) Whether to introduce a reshuffle (to possibly
            redistribute the work) if there is more than one element in the
            collection. Defaults to True.
    """
    # Though str and dict are technically iterable, we disallow them
    # as using the characters or keys respectively is almost certainly
    # not the intent.
    if not isinstance(elements, Iterable) or isinstance(elements, (dict, str)):
      raise TypeError('elements must be a list of elements')

    if elements:
      # Normalize elements to be all dicts or all primitives.
      has_dict = False
      has_non_dict = False
      for e in elements:
        if isinstance(e, dict):
          has_dict = True
        else:
          has_non_dict = True
        if has_dict and has_non_dict:
          break

      if has_dict and has_non_dict:
        elements = [
            e if isinstance(e, dict) else {
                'element': e
            } for e in elements

View on GitHub (pinned to 12126d8942)