apache/beam · error · ValueError

Multi-level initial splitting is not supported. Expected…

Error message

Multi-level initial splitting is not supported. Expected start and stop positions to be None. Received %r and %r respectively.

What it means

ConcatSource.split() delegates initial splitting to its sub-sources and does not support multi-level splitting. If the framework passes non-None start_position or stop_position (meaning an outer split already constrained the range), it raises ValueError because splitting a range-restricted concatenation cannot be expressed here.

Solutions

  1. Call split() with only desired_bundle_size, leaving start_position/stop_position as None
  2. Flatten nested ConcatSources so only one level of splitting occurs
  3. Implement positions-aware splitting in a custom Source subclass if needed

Example fix

// before
bundles = concat_source.split(64 * 1024 * 1024, start_pos, stop_pos)
// after
bundles = concat_source.split(desired_bundle_size=64 * 1024 * 1024)  # positions must be None
Defensive patterns

Strategy: validation

Validate before calling

assert start_position is None and stop_position is None, 'ConcatSource.split supports only unbounded initial splitting'

Try / catch

try:
    bundles = source.split(size, start, stop)
except ValueError:
    bundles = source.split(size)  # retry without position bounds

Prevention

When it happens

Trigger: Calling concat_source.split(desired_bundle_size, start_position, stop_position) with either position set; custom runner or custom source code that splits an already-split ConcatSource bundle.

Common situations: Custom composite sources layered over ConcatSource; runners or test harnesses performing repeated/bounded splitting; Beam version changes altering split contracts.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/io/concat_source.py:54

  to create the union of several reads.
  """
  def __init__(self, sources):
    self._source_bundles = [
        source if isinstance(source, iobase.SourceBundle) else
        iobase.SourceBundle(None, source, None, None) for source in sources
    ]

  @property
  def sources(self):
    return [s.source for s in self._source_bundles]

  def estimate_size(self):
    return sum(s.source.estimate_size() for s in self._source_bundles)

  def split(
      self, desired_bundle_size=None, start_position=None, stop_position=None):
    if start_position or stop_position:
      raise ValueError(
          'Multi-level initial splitting is not supported. Expected start and '
          'stop positions to be None. Received %r and %r respectively.' %
          (start_position, stop_position))

    for source in self._source_bundles:
      # We assume all sub-sources to produce bundles that specify weight using
      # the same unit. For example, all sub-sources may specify the size in
      # bytes as their weight.
      for bundle in source.source.split(desired_bundle_size,
                                        source.start_position,
                                        source.stop_position):
        yield bundle

  def get_range_tracker(self, start_position=None, stop_position=None):
    if start_position is None:
      start_position = (0, None)
    if stop_position is None:
      stop_position = (len(self._source_bundles), None)

View on GitHub (pinned to 12126d8942)