apache/beam · error · ValueError

Namespaces must be an iterable, not a string

Error message

Namespaces must be an iterable, not a string

What it means

MetricsFilter.with_namespaces() requires an iterable of namespaces; passing a single string raises ValueError so that the string is not silently split into characters. Use with_namespace for a single value.

Source

Thrown at sdks/python/apache_beam/metrics/metric.py:373

    return self.with_name(name).with_namespace(namespace)

  def with_name(self, name: str) -> 'MetricsFilter':
    return self.with_names([name])

  def with_names(self, names: Iterable[str]) -> 'MetricsFilter':
    if isinstance(names, str):
      raise ValueError('Names must be a collection, not a string')

    self._names.update(names)
    return self

  def with_namespace(self, namespace: Union[type, str]) -> 'MetricsFilter':
    return self.with_namespaces([namespace])

  def with_namespaces(
      self, namespaces: Iterable[Union[type, str]]) -> 'MetricsFilter':
    if isinstance(namespaces, str):
      raise ValueError('Namespaces must be an iterable, not a string')

    self._namespaces.update([Metrics.get_namespace(ns) for ns in namespaces])
    return self

  def with_step(self, step: str) -> 'MetricsFilter':
    return self.with_steps([step])

  def with_steps(self, steps: Iterable[str]) -> 'MetricsFilter':
    if isinstance(steps, str):
      raise ValueError('Steps must be an iterable, not a string')

    self._steps.update(steps)
    return self


class Lineage:
  """Standard collection of metrics used to record source and sinks information
  for lineage tracking."""

View on GitHub (pinned to 12126d8942)

Solutions

  1. Wrap in a list: with_namespaces(['myns']) or with_namespaces([MyClass]).
  2. Use with_namespace('myns') for a single namespace.
  3. Ensure the argument is a list/set/generator/tuple, not str/bytes.

Example fix

- MetricsFilter().with_namespaces('myns')
+ MetricsFilter().with_namespaces(['myns'])
Defensive patterns

Strategy: validation

Validate before calling

namespaces = [ns] if isinstance(ns, (str, type)) else list(ns)
filter_ = MetricsFilter().with_namespaces(namespaces)

Type guard

def as_namespace_list(namespaces):
    return [namespaces] if isinstance(namespaces, (str, type)) else list(namespaces)

Try / catch

try:
    f = MetricsFilter().with_namespaces(namespaces)
except ValueError:
    f = MetricsFilter().with_namespaces([namespaces])

Prevention

When it happens

Trigger: MetricsFilter().with_namespaces('myns') or with_namespaces(SomeClass) — a str (or other non-iterable) instead of a collection of namespaces; reached indirectly through with_namespace only if the caller wraps wrongly.

Common situations: Querying pipeline metrics and passing one namespace directly; namespaces built from class types being passed without wrapping.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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