apache/beam · error · ValueError

Expected split of source %r at fraction %r after reading

Error message

Expected split of source %r at fraction %r after reading %d elements to fail. But splitting succeeded with result %r.

What it means

This ValueError is thrown by the Beam iobase source test harness when a test asserts that a source's split_at_fraction() must fail at a given fraction, but the split actually succeeded and returned a residual source. It flags a source whose dynamic work rebalancing behavior contradicts the expected outcome declared by the test.

Solutions

  1. Inspect the source's split_at_fraction/RangeTracker.try_split to see why it succeeds at that fraction and fix the source if success is incorrect.
  2. Change expected_outcome to ExpectedSplitOutcome.MUST_BE_CONSISTENT_IF_SUCCEEDS if success is legitimate.
  3. Pick a split fraction where the source is genuinely expected to refuse to split (e.g. fractions outside the remaining range).
  4. Log the returned split_result to confirm which primary/residual ranges the split produced before deciding the expected outcome.

Example fix

// before
assert_split_at_fraction_behavior(source, ExpectedSplitOutcome.MUST_FAIL, 0.5, 3)
// after
assert_split_at_fraction_behavior(source, ExpectedSplitOutcome.MUST_BE_CONSISTENT_IF_SUCCEEDS, 0.5, 3)
Defensive patterns

Strategy: validation

Validate before calling

from apache_beam.io.iobase import ExpectedSplitOutcome
assert isinstance(expected_outcome, ExpectedSplitOutcome)
assert expected_outcome == ExpectedSplitOutcome.MUST_FAIL
# Optionally probe: result = source.split_at_fraction(fraction) and confirm it's None

Type guard

def is_valid_outcome(v):
    return isinstance(v, ExpectedSplitOutcome)

Try / catch

try:
    assert_split_at_fraction_behavior(source, ExpectedSplitOutcome.MUST_FAIL, fraction, n)
except ValueError as e:
    logging.error('Split behavior mismatch: %s', e)

Prevention

When it happens

Trigger: Calling assert_split_at_fraction_behavior or assert_split_at_fraction_binary with expected_outcome=ExpectedSplitOutcome.MUST_FAIL on a source whose split_at_fraction() returns a non-None (successful) result after reading num_items_to_read_before_split items.

Common situations: Writing or porting a custom iobase.BoundedSource/RangeTracker whose split_at_fraction implementation succeeds at fractions the test expects to fail; changing a RangeTracker's try_split logic after a version upgrade; copy-pasting MUST_FAIL from another test where the source semantics differed.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/b777bda37c8fd912. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/source_test_utils.py:335

          '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)
  current_items.extend([value for value in reader_iter])

  residual_range = (
      split_result[0], stop_position_before_split) if split_result else None

  return _verify_single_split_fraction_result(
      source,

View on GitHub (pinned to 12126d8942)