apache/beam · error · ValueError
Positions claimed should strictly increase. Trying to claim
Error message
Positions claimed should strictly increase. Trying to claim position %d while last claim attempt was %d.
What it means
OffsetRestrictionTracker.try_claim() requires claimed positions to strictly increase so Beam can track deterministic progress through a restriction. Beam raises this ValueError when a position is claimed that is less than or equal to the previous claim attempt, since it would loop forever or double-claim work.
Source
Thrown at sdks/python/apache_beam/io/restriction_trackers.py:120
elif self._range.stop == self._range.start:
# If self._current_position is not None, we must be done.
fraction = 1.0
else:
fraction = (
float(self._current_position - self._range.start) /
(self._range.stop - self._range.start))
return RestrictionProgress(fraction=fraction)
def start_position(self):
return self._range.start
def stop_position(self):
return self._range.stop
def try_claim(self, position):
if (self._last_claim_attempt is not None and
position <= self._last_claim_attempt):
raise ValueError(
'Positions claimed should strictly increase. Trying to claim '
'position %d while last claim attempt was %d.' %
(position, self._last_claim_attempt))
self._last_claim_attempt = position
if position < self._range.start:
raise ValueError(
'Position to be claimed cannot be smaller than the start position '
'of the range. Tried to claim position %r for the range [%r, %r)' %
(position, self._range.start, self._range.stop))
if self._range.start <= position < self._range.stop:
self._current_position = position
return True
return False
def try_split(self, fraction_of_remainder):View on GitHub (pinned to 12126d8942)
Solutions
- Advance the position monotonically before each try_claim call
- Never reuse a position value across try_claim calls; keep a separate cursor
- If resuming after checkpoint, resume from stop_position()/current_position rather than the original start
- Restructure loops that decrement or reset the index
Example fix
// before for attempt in range(3): tracker.try_claim(position) # same position retried // after tracker.try_claim(position) position += 1 # always move forward before the next claim
Defensive patterns
Strategy: validation
Validate before calling
def safe_claim(tracker, position, last):
if last is not None and position <= last:
raise ValueError('positions must strictly increase')
return tracker.try_claim(position) Try / catch
try:
tracker.try_claim(position)
except ValueError as e:
logger.error('Non-monotonic claim: %s', e)
position = tracker.current_position() + 1 Prevention
- Keep a single monotonic cursor variable for claims
- Never reset the cursor after checkpoint — resume from tracker state
- Avoid retry loops that re-claim the same position
When it happens
Trigger: Calling try_claim with the same position twice (position == last claim) or going backwards (position < last claim), e.g. re-claiming after a failed claim attempt or a loop that decrements the cursor.
Common situations: Buggy custom SDF loops that retry an offset, iterators that restart from the beginning, or checkpoint/resume logic that resets the position variable but not the tracker.
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
- Initializing SDFBoundedSourceRestrictionTracker requires a _
- SDFBoundedSourceRestrictionProvider can only utilize Bounded
- OffsetRestrictionTracker is not done since work in range [%s
- Position to be claimed cannot be smaller than the start posi
- UnboundedSource restriction was neither finished nor checkpo
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/cc396b673a5776a9.
Report an issue: GitHub.