apache/beam · error · ValueError

Claim ' ' is before start

Error message

Claim '%s' is before start '%s'

What it means

The same try_claim() also validates the lower bound of the restriction: it raises ValueError when a claimed position is before the restriction's start position. This keeps claims inside the granted restriction.

Solutions

  1. Initialize the claim cursor to the restriction's start position (self.current_restriction().start) before the process loop.
  2. Fix restriction construction so start matches where iteration actually begins.
  3. Clamp positions to the restriction start before calling try_claim.

Example fix

// before
pos = 0
while self.try_claim(pos):
  process(pos); pos += 1
// after
pos = self.current_restriction().start
while self.try_claim(pos):
  process(pos); pos += 1
Defensive patterns

Strategy: validation

Validate before calling

start = tracker.current_restriction().start
if position < start:
  position = start  # clamp before claiming

Try / catch

try:
  tracker.try_claim(position)
except ValueError as e:
  logging.error('claim before restriction start: %s', e)

Prevention

When it happens

Trigger: Calling try_claim(position) where self._start_position is not None and position < self._start_position, e.g. iterating a cursor initialized to an offset before the restriction start (common with default cursors of 0 when the restriction starts elsewhere).

Common situations: Custom RestrictionTracker whose process loop starts from element index 0 instead of restriction.start(); off-by-one in restriction construction where a restriction like (5,10) is iterated from 0.

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/3d45018603e4673c. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/range_trackers.py:251

    self._lock = threading.Lock()
    self._last_claim = self.UNSTARTED

  def start_position(self):
    return self._start_position

  def stop_position(self):
    with self._lock:
      return self._stop_position

  def try_claim(self, position):
    with self._lock:
      if self._last_claim is not self.UNSTARTED and position < self._last_claim:
        raise ValueError(
            "Positions must be claimed in order: "
            "claim '%s' attempted after claim '%s'" %
            (position, self._last_claim))
      elif self._start_position is not None and position < self._start_position:
        raise ValueError(
            "Claim '%s' is before start '%s'" %
            (position, self._start_position))
      if self._stop_position is None or position < self._stop_position:
        self._last_claim = position
        return True
      else:
        return False

  def position_at_fraction(self, fraction):
    return self.fraction_to_position(
        fraction, self._start_position, self._stop_position)

  def try_split(self, position):
    with self._lock:
      if ((self._stop_position is not None and position >= self._stop_position)
          or (self._start_position is not None and
              position <= self._start_position)):
        _LOGGER.debug(

View on GitHub (pinned to 12126d8942)