{"record":{"id":"0124f43b9140fafc","repo":"apache/beam","slug":"split-fraction-must-be-within-the-range-0-1","errorCode":null,"errorMessage":"Split fraction must be within the range [0,1]","messagePattern":"Split fraction must be within the range \\[0,1\\]","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/source_test_utils.py","lineNumber":315,"sourceCode":"\n  stop_position_before_split = range_tracker.stop_position()\n  split_result = range_tracker.try_split(suggested_split_position)\n\n  if split_result is not None:\n    if len(split_result) != 2:\n      raise ValueError(\n          'Split result must be a tuple that contains split '\n          'position and split fraction. Received: %r' % (split_result, ))\n\n    if range_tracker.stop_position() != split_result[0]:\n      raise ValueError(\n          'After a successful split, the stop position of the '\n          'RangeTracker must be the same as the returned split '\n          'position. Observed %r and %r which are different.' %\n          (range_tracker.stop_position() % (split_result[0], )))\n\n    if split_fraction < 0 or split_fraction > 1:\n      raise ValueError(\n          'Split fraction must be within the range [0,1]',\n          'Observed split fraction was %r.' % (split_result[1], ))\n\n  stop_position_after_split = range_tracker.stop_position()\n  if split_result and stop_position_after_split == stop_position_before_split:\n    raise ValueError(\n        'Stop position %r did not change after a successful '\n        'split of source %r at fraction %r.' %\n        (stop_position_before_split, source, split_fraction))\n\n  if expected_outcome == ExpectedSplitOutcome.MUST_SUCCEED_AND_BE_CONSISTENT:\n    if not split_result:\n      raise ValueError(\n          'Expected split of source %r at fraction %r to be '\n          'successful after reading %d elements. But '\n          'the split failed.' %\n          (source, split_fraction, num_items_to_read_before_split))\n  elif expected_outcome == ExpectedSplitOutcome.MUST_FAIL:","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/source_test_utils.py#L297-L333","documentation":"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).","triggerScenarios":"_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.","commonSituations":"Custom RangeTracker implementations returning position/stop without normalizing, or computing fraction against the wrong total size in offsets-based sources.","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."],"exampleFix":"// before\nreturn (pos, pos)\n// after\nfraction = (pos - self._start) / float(self._stop - self._start)\nassert 0.0 <= fraction <= 1.0\nreturn (pos, fraction)","handlingStrategy":"validation","validationCode":"res = tracker.try_split(pos)\nif res is not None:\n    assert 0.0 <= res[1] <= 1.0, \"fraction out of [0,1]: %r\" % (res[1],)","typeGuard":"def fraction_in_unit_interval(res):\n    return res is None or (isinstance(res[1], float) and 0.0 <= res[1] <= 1.0)","tryCatchPattern":"try:\n    source_test_utils.assert_split_at_fraction_behavior(src, n, f, outcome)\nexcept ValueError as e:\n    if \"range [0,1]\" in str(e):\n        logger.error(\"bad split fraction: %s\", e)\n    raise","preventionTips":["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)"],"tags":["apache-beam","range-tracker","split-fraction","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}