apache/beam · error · ValueError
Expected split of source %r at fraction %r to be successful…
Error message
Expected split of source %r at fraction %r to be successful after reading %d elements. But the split failed.
What it means
Raised by _assert_split_at_fraction_behavior when the test expects the split to succeed (ExpectedSplitOutcome.MUST_SUCCEED_AND_BE_CONSISTENT) but RangeTracker.try_split returned None after reading num_items_to_read_before_split elements at the requested fraction. This means the source/RangeTracker refused a dynamic split that Beam's harness expects to be possible, defeating work rebalancing. It is an expectation mismatch between the test's declared outcome and the tracker's actual behavior.
Solutions
- Implement try_split in the source's RangeTracker so it actually splits at the suggested position instead of always returning None.
- If the source legitimately cannot split, change the test expectation to ExpectedSplitOutcome.MUST_FAIL or DONOT_KNOW.
- Verify the chosen split_fraction leaves a non-empty remainder range (avoid splitting at ~0.0 or ~1.0 boundaries that the tracker rejects).
- Ensure position_at_fraction maps the fraction to a valid position inside [start, stop) so the split isn't declined as out-of-range.
Example fix
// before: always refuse split
def try_split(self, fraction):
return None
// after
def try_split(self, fraction):
pos = self.position_at_fraction(fraction)
if pos is None or pos <= self.start_position() or pos >= self.stop_position():
return None
self._stop = pos
return (pos, fraction) Defensive patterns
Strategy: validation
Validate before calling
pos = tracker.position_at_fraction(f)
will_split = tracker.try_split(pos) is not None
if expected_outcome == ExpectedSplitOutcome.MUST_SUCCEED_AND_BE_CONSISTENT and not will_split:
pytest.fail("tracker refuses expected split at fraction %r" % f) Type guard
def supports_splitting(source):
return not type(source.get_range_tracker(None, None)).try_split.__qualname__.startswith("RangeTracker") or True Try / catch
try:
source_test_utils.assert_split_at_fraction_behavior(src, n, f, outcome)
except ValueError as e:
if "to be successful" in str(e) or "the split failed" in str(e):
logger.error("tracker declined expected split: %s", e)
raise Prevention
- Implement try_split rather than unconditionally returning None
- Match test expectations (MUST_FAIL vs MUST_SUCCEED) to actual tracker capability
- Avoid split fractions at range boundaries the tracker legitimately rejects
- Ensure position_at_fraction yields an interior position of [start, stop)
When it happens
Trigger: assert_split_at_fraction_behavior(source, n, fraction, ExpectedSplitOutcome.MUST_SUCCEED_AND_BE_CONSISTENT) where the source's RangeTracker returns None from try_split at that point — e.g. a tracker that never supports splitting, or rejects splits too close to start/stop boundaries.
Common situations: Custom sources that conservatively return None from try_split (unsplittable), split_fraction chosen where remaining range is too small, or sources whose RangeTracker disables splitting below a size threshold while the test asserts success.
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
- After a successful split, the stop position of the…
- Split result must be a tuple that contains split position…
- Stop position %r did not change after a successful split of…
- End offset must not be 'None'
- Error determining if
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/5071ecc81dff0f13.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/io/source_test_utils.py:328
'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:
if split_result:
raise ValueError(
'Expected split of source %r at fraction %r after '
'reading %d elements to fail. But splitting '
'succeeded with result %r.' % (
source,
split_fraction,
num_items_to_read_before_split,
split_result))
elif (expected_outcome
!= ExpectedSplitOutcome.MUST_BE_CONSISTENT_IF_SUCCEEDS):
raise ValueError('Unknown type of expected outcome: %r' % expected_outcome)View on GitHub (pinned to 12126d8942)