apache/beam · error · ValueError
Positions must be claimed in order: claim
Error message
Positions must be claimed in order: claim '%s' attempted after claim '%s'
What it means
OffsetRangeTracker (restrictions-based) try_claim() enforces claim ordering. It raises ValueError when a position is claimed that is strictly less than the last claimed position, violating the requirement that positions are claimed in monotonically increasing order.
Solutions
- Ensure the process loop iterates positions in strictly increasing order and never rewinds.
- After a retriable failure, restart processing from restriction_tracker.current_restriction().start with a fresh tracker rather than re-claiming older positions on the same tracker.
- Review try_split/primary-and-residual logic so the primary restriction (which keeps claiming) starts where the residual begins, never before the last claim.
Example fix
// before
pos = start
while try_claim(pos):
process(pos)
if error: pos = start # rewinds
pos += 1
// after
pos = start
while try_claim(pos):
try:
process(pos)
except RetryableError:
raise # let runner restart with fresh restriction
pos += 1 Defensive patterns
Strategy: validation
Validate before calling
if tracker._last_claim is not tracker.UNSTARTED and position < tracker._last_claim:
raise ValueError('position must not go backwards') Try / catch
try:
ok = tracker.try_claim(position)
except ValueError:
logging.error('claim order violated; restarting from restriction start') Prevention
- Iterate positions strictly in increasing order
- Never rewind cursors on retriable errors; restart with a fresh tracker
- Test try_split implementations for overlap-free primary/residual ranges
When it happens
Trigger: Calling try_claim(position) with position < self._last_claim after a prior successful claim, e.g. a DoFn process loop that rewinds its cursor, or a split/resume path that restarts from an earlier position on the same tracker instance.
Common situations: Custom restriction providers (RestrictionTracker) where the process function re-processes elements after a retriable failure without creating a fresh tracker; incorrectly implemented try_split producing overlapping claims.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Claim ' ' is before start
- A BigQuery table or a query must be specified
- A cluster_identifier should be Optional[Union[str…
- A context manager constructor (not a fully constructed…
- A has been supplied to the model handler, but the required…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/17d7650679652072.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/io/range_trackers.py:246
UNSTARTED = object()
def __init__(self, start_position=None, stop_position=None):
self._start_position = start_position
self._stop_position = stop_position
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):View on GitHub (pinned to 12126d8942)