apache/beam · error

fraction must be between 0 and 1

Error message

fraction must be between 0 and 1

What it means

idRangeTracker.TrySplit implements the Beam restriction-tracker split protocol for MongoDB _id range restrictions. The split fraction must lie in [0,1]; anything outside cannot be interpreted as a proportional split, so the tracker refuses immediately. This is a defensive check required by the Beam split contract.

Source

Thrown at sdks/go/pkg/beam/io/mongodbio/id_range_tracker.go:98

}

// GetError returns the error associated with the tracker, if any.
func (rt *idRangeTracker) GetError() error {
	return rt.err
}

// TrySplit splits the underlying restriction into a primary and residual restriction based on the
// fraction of remaining work the primary should be responsible for. The restriction may be modified
// as a result of the split. The primary is a copy of the tracker's restriction after the split.
// If the fraction is 1 or all work has already been claimed, returns the full restriction as the
// primary and nil as the residual. If the fraction is 0, stops the tracker, cuts off any remaining
// work from its underlying restriction, and returns a residual representing all remaining work.
// If the fraction is between 0 and 1, attempts to split the remaining work of the underlying
// restriction into two sub-restrictions based on the fraction and assigns them to the primary and
// residual respectively. Returns an error if the split cannot be performed.
func (rt *idRangeTracker) TrySplit(fraction float64) (primary, residual any, err error) {
	if fraction < 0 || fraction > 1 {
		return nil, nil, errors.New("fraction must be between 0 and 1")
	}

	done, remaining := rt.cutRestriction()

	if fraction == 1 || remaining.Count == 0 {
		return rt.rest, nil, nil
	}

	if fraction == 0 {
		rt.rest = done
		return rt.rest, remaining, nil
	}

	ctx := context.Background()

	primaryRem, resid, err := remaining.FractionSplits(ctx, rt.collection, fraction)
	if err != nil {
		return nil, nil, err

View on GitHub (pinned to 12126d8942)

Solutions

  1. Clamp or validate the fraction before calling TrySplit: math.Max(0, math.Min(1, fraction)).
  2. If the fraction is computed from a percentage, divide by 100 (150% -> 1.5 is still invalid; a split of 'all work' is fraction 1).
  3. Review custom runner/splitter code deriving the fraction to fix the ratio computation at the source.

Example fix

// before
primary, residual, err := tracker.TrySplit(splitPct) // splitPct = 150
// after
f := math.Max(0, math.Min(1, splitPct/100))
primary, residual, err := tracker.TrySplit(f)
Defensive patterns

Strategy: validation

Validate before calling

if fraction < 0 || fraction > 1 {
    return fmt.Errorf("split fraction %v out of [0,1]", fraction)
}
tracker.TrySplit(fraction)

Type guard

func validFraction(f float64) bool { return f >= 0 && f <= 1 && !math.IsNaN(f) }

Try / catch

primary, residual, err := tracker.TrySplit(f)
if err != nil {
    return fmt.Errorf("split failed: %w", err)
}

Prevention

When it happens

Trigger: Calling TrySplit(fraction) with fraction < 0 or fraction > 1, e.g. TrySplit(1.5) or TrySplit(-0.1), whether invoked directly in tests or via a custom SplittableDoFn runner/splitter that computes a bad fraction.

Common situations: Custom split logic computing a fraction from a mis-derived ratio (e.g. integer division or mixing up numerator/denominator); framework code passing an unclamped user-configured split percentage like 150 instead of 1.5 or 0.5.

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


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