apache/beam · error · ValueError
Split fraction must be within the range [0,1]
Error message
Split fraction must be within the range [0,1]
What it means
Raised when a successful try_split returns a split fraction outside [0, 1]. The split fraction reported by try_split must be the fraction of remaining work represented by the primary (current) range and must lie in the unit interval. This catches a custom RangeTracker computing or reporting a nonsensical fraction (e.g. a raw position or a percentage).
Source
Thrown at sdks/python/apache_beam/io/source_test_utils.py:315
stop_position_before_split = range_tracker.stop_position()
split_result = range_tracker.try_split(suggested_split_position)
if split_result is not None:
if len(split_result) != 2:
raise ValueError(
'Split result must be a tuple that contains split '
'position and split fraction. Received: %r' % (split_result, ))
if range_tracker.stop_position() != split_result[0]:
raise ValueError(
'After a successful split, the stop position of the '
'RangeTracker must be the same as the returned split '
'position. Observed %r and %r which are different.' %
(range_tracker.stop_position() % (split_result[0], )))
if split_fraction < 0 or split_fraction > 1:
raise ValueError(
'Split fraction must be within the range [0,1]',
'Observed split fraction was %r.' % (split_result[1], ))
stop_position_after_split = range_tracker.stop_position()
if split_result and stop_position_after_split == stop_position_before_split:
raise ValueError(
'Stop position %r did not change after a successful '
'split of source %r at fraction %r.' %
(stop_position_before_split, source, split_fraction))
if expected_outcome == ExpectedSplitOutcome.MUST_SUCCEED_AND_BE_CONSISTENT:
if not split_result:
raise ValueError(
'Expected split of source %r at fraction %r to be '
'successful after reading %d elements. But '
'the split failed.' %
(source, split_fraction, num_items_to_read_before_split))
elif expected_outcome == ExpectedSplitOutcome.MUST_FAIL:View on GitHub (pinned to 12126d8942)
Solutions
- Return fraction = (split_position - start_position) / (stop_position - start_position), clamped to [0,1].
- Assert the computed fraction is within [0,1] inside try_split before returning.
- If the correct fraction cannot be determined, still return a valid value per contract or return None to decline the split.
- Reuse Beam's built-in RangeTracker / OffsetRangeTracker instead of custom math.
Example fix
// before return (pos, pos) // after fraction = (pos - self._start) / float(self._stop - self._start) assert 0.0 <= fraction <= 1.0 return (pos, fraction)
Defensive patterns
Strategy: validation
Validate before calling
res = tracker.try_split(pos)
if res is not None:
assert 0.0 <= res[1] <= 1.0, "fraction out of [0,1]: %r" % (res[1],) Type guard
def fraction_in_unit_interval(res):
return res is None or (isinstance(res[1], float) and 0.0 <= res[1] <= 1.0) Try / catch
try:
source_test_utils.assert_split_at_fraction_behavior(src, n, f, outcome)
except ValueError as e:
if "range [0,1]" in str(e):
logger.error("bad split fraction: %s", e)
raise Prevention
- Compute fraction as (pos-start)/(stop-start) and clamp to [0,1]
- Never return raw positions where a fraction is expected
- Cover try_split with boundary-value tests (fractions 0, 0.5, 1)
When it happens
Trigger: _assert_split_at_fraction_behavior receives split_result with split_result[1] < 0 or > 1 after a successful try_split, e.g. returning a position instead of a fraction, or fraction > 1 from a wrong denominator.
Common situations: Custom RangeTracker implementations returning position/stop without normalizing, or computing fraction against the wrong total size in offsets-based sources.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- The first record [starting at %d] must be at a split point
- Trying to return record [starting at %d] which is before the
- max_insert_payload_size can only go up to 10485760 bytes, as
- Start offset must not be 'None'
- End offset must not be 'None'
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0124f43b9140fafc.
Report an issue: GitHub.