apache/beam · error · ValueError

is not iterable

Error message

%s is not iterable

What it means

Beam's typehint machinery raises this when asked for the element type of a type hint that is not iterable. iterables_type_or_inner_type only extracts inner_type from Iterable-compatible hints; anything else fails. It means you passed a non-iterable type hint where Beam expects a stream of elements.

Solutions

  1. Change the type hint to an iterable form, e.g. List[int], Sequence[Tuple[K, V]], or Iterable[T].
  2. If the value is a single element, wrap it in a list or use a singleton PCollection instead of a side input.
  3. Inspect the hint with apache_beam.typehints.is_consistent_with(hint, Iterable[Any]) before passing it.
  4. If the hint is genuinely unknown, use Any inside an iterable: Iterable[Any].

Example fix

// before
with beam.Pipeline() as p:
  res = pc | beam.FlatMap(lambda x: x * 2).with_input_types(int)
// after
res = pc | beam.FlatMap(lambda x: x * 2).with_input_types(Iterable[int])
Defensive patterns

Strategy: type-guard

Validate before calling

from apache_beam.typehints import Iterable, is_consistent_with
if not is_consistent_with(hint, Iterable[Any]):
    raise TypeError(f'expected iterable type hint, got {hint}')

Type guard

def is_iterable_hint(hint) -> bool:
    from apache_beam.typehints import Iterable, is_consistent_with
    return is_consistent_with(hint, Iterable[Any])

Try / catch

try:
    inner = iterables_type_or_inner_type(hint)
except ValueError:
    inner = None  # handle non-iterable hint
if inner is None:
    hint = Iterable[Any]  # or wrap value in a list

Prevention

When it happens

Trigger: Calling iterables_type_or_inner_type (directly or via PTransform type inference, e.g. FlatMap/CoGroupByKey expansions) with a hint like int, Dict[str, str], or Any not consistent with Iterable[Any].

Common situations: Passing a scalar side input to a transform that requires a PCollection; annotating a DoFn input with a non-iterable hint; CoGroupByKey inputs hinted as dict instead of list/tuple of values.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/typehints/typehints.py:1605

  if isinstance(type_hint, typing.TypeVar):
    return typing.Any
  if isinstance(type_hint, AnyTypeConstraint):
    return type_hint
  if isinstance(type_hint, UnionConstraint):
    yielded_types = set()
    for typ in type_hint.inner_types():
      yielded_types.add(get_yielded_type(typ))
    return Union[yielded_types]
  if is_consistent_with(type_hint, Iterator[Any]):
    return type_hint.yielded_type
  if is_consistent_with(type_hint, Tuple[Any, ...]):
    if isinstance(type_hint, TupleConstraint):
      return Union[type_hint.tuple_types]
    else:  # TupleSequenceConstraint
      return type_hint.inner_type
  if is_consistent_with(type_hint, Iterable[Any]):
    return type_hint.inner_type
  raise ValueError('%s is not iterable' % type_hint)


def coerce_to_kv_type(element_type, label=None, side_input_producer=None):
  """Attempts to coerce element_type to a compatible kv type.

  Raises an error on failure.
  """
  if side_input_producer:
    consumer = 'side-input of %r (producer: %r)' % (label, side_input_producer)
  else:
    consumer = '%r' % label

  # If element_type is not specified, then treat it as `Any`.
  if not element_type:
    return KV[Any, Any]
  elif isinstance(element_type, TupleHint.TupleConstraint):
    if len(element_type.tuple_types) == 2:
      return element_type

View on GitHub (pinned to 12126d8942)