apache/beam · error · ValueError

Initializing SDFBoundedSourceRestrictionTracker requires a _

Error message

Initializing SDFBoundedSourceRestrictionTracker requires a _SDFBoundedSourceRestriction. Got %s instead.

What it means

SDFBoundedSourceRestrictionTracker.__init__ requires its restriction argument to be a _SDFBoundedSourceRestriction (the internal wrapper pairing a SourceBundle with a RangeTracker). Passing any other restriction type (e.g. a raw OffsetRange from ordinary SDF code) raises ValueError. This is an internal invariant for the legacy-BoundedSource-to-SDF adapter.

Source

Thrown at sdks/python/apache_beam/io/iobase.py:1805

                    split_pos,
                    stop_pos)))
    except Exception:
      # For any exceptions from underlying trySplit calls, the wrapper will
      # think that the source refuses to split at this point. In this case,
      # no split happens at the wrapper level.
      return None


class _SDFBoundedSourceRestrictionTracker(RestrictionTracker):
  """An `iobase.RestrictionTracker` implementations for wrapping BoundedSource
  with SDF. The tracked restriction is a _SDFBoundedSourceRestriction, which
  wraps SourceBundle and RangeTracker.

  Delegated RangeTracker guarantees synchronization safety.
  """
  def __init__(self, restriction):
    if not isinstance(restriction, _SDFBoundedSourceRestriction):
      raise ValueError(
          'Initializing SDFBoundedSourceRestrictionTracker'
          ' requires a _SDFBoundedSourceRestriction. Got %s instead.' %
          restriction)
    self.restriction = restriction

  def current_progress(self) -> RestrictionProgress:
    return RestrictionProgress(
        fraction=self.restriction.range_tracker().fraction_consumed())

  def current_restriction(self):
    self.restriction.range_tracker()
    return self.restriction

  def start_pos(self):
    return self.restriction.range_tracker().start_position()

  def stop_pos(self):
    return self.restriction.range_tracker().stop_position()

View on GitHub (pinned to 12126d8942)

Solutions

  1. Let Beam create the tracker via SDFBoundedSourceRestrictionProvider instead of constructing it manually.
  2. If you must construct it, build the restriction via _SDFBoundedSourceRestriction(SourceBundle(...), RangeTracker...).
  3. Do not override initial_restriction/split_restriction in a subclass with non-wrapper restriction types.

Example fix

# before
SDFBoundedSourceRestrictionTracker(OffsetRange(0, 100))
# after
restriction = _SDFBoundedSourceRestriction(bundle, range_tracker)
SDFBoundedSourceRestrictionTracker(restriction)
Defensive patterns

Strategy: type-guard

Validate before calling

from apache_beam.io.iobase import _SDFBoundedSourceRestriction
assert isinstance(restriction, _SDFBoundedSourceRestriction), type(restriction)

Type guard

def is_sdf_bounded_restriction(restriction) -> bool:
    from apache_beam.io.iobase import _SDFBoundedSourceRestriction
    return isinstance(restriction, _SDFBoundedSourceRestriction)

Try / catch

try:
    tracker = SDFBoundedSourceRestrictionTracker(restriction)
except ValueError as e:
    log.error('Wrong restriction type %s', type(restriction))

Prevention

When it happens

Trigger: Constructing SDFBoundedSourceRestrictionTracker directly with a non _SDFBoundedSourceRestriction object, or a custom restriction provider returning a foreign restriction type for a BoundedSource-based DoFn.

Common situations: Custom runners or testing harnesses instantiating the tracker manually; subclassing the provider and overriding initial_restriction with a different restriction type.

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