apache/beam · error

values below expected: %v

Error message

values below expected: %v

What it means

Inside EqualsFloat's thresholdFn.ProcessElement, each observed value is compared against expected ± threshold. Values smaller than the allowed lower bound are collected into `tooLow` and reported as 'values below expected: %v'. The joined error strings fail the assertion, listing which observed values fell short of expected-threshold.

Source

Thrown at sdks/go/pkg/beam/testing/passert/floats.go:108

	for i := 0; i < len(observedValues); i++ {
		delta := observedValues[i] - expectedValues[i]
		if delta > f.Threshold {
			tooHigh = append(tooHigh, fmt.Sprintf("%v > %v,", observedValues[i], expectedValues[i]))
		} else if delta < f.Threshold*-1 {
			tooLow = append(tooLow, fmt.Sprintf("%v < %v,", observedValues[i], expectedValues[i]))
		}
	}
	if len(tooLow)+len(tooHigh) == 0 {
		return nil
	}
	errorStrings := []string{}
	if len(tooLow) != 0 {
		errorStrings = append(errorStrings, fmt.Sprintf("values below expected: %v", tooLow))
	}
	if len(tooHigh) != 0 {
		errorStrings = append(errorStrings, fmt.Sprintf("values above expected: %v", tooHigh))
	}
	return errors.New(strings.Join(errorStrings, "\n"))
}

// AllWithinBounds checks that a PCollection of numeric types is within the bounds
// [lo, high]. Checks for case where bounds are flipped and swaps them so the bounds
// passed to the doFn are always lo <= hi.
func AllWithinBounds(s beam.Scope, col beam.PCollection, lo, hi float64) {
	t := beam.ValidateNonCompositeType(col)
	validateNonComplexNumber(t.Type())
	if lo > hi {
		lo, hi = hi, lo
	}
	s = s.Scope(fmt.Sprintf("passert.AllWithinBounds([%v, %v])", lo, hi))
	beam.ParDo0(s, &boundsFn{Lo: lo, Hi: hi}, beam.Impulse(s), beam.SideInput{Input: col})
}

type boundsFn struct {
	Lo, Hi float64
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Widen the threshold parameter to accommodate legitimate floating-point drift
  2. Inspect the listed values to determine which pipeline stage produced wrong results
  3. Compare sorted/deterministic aggregation if order-dependent float accumulation is the cause
  4. Use exact-value types (int64) or AllWithinBounds if tolerance semantics are unclear

Example fix

// before
passert.EqualsFloat(s, averages, 1.0, 1e-12) // 0.9999999995 reported below expected
// after
passert.EqualsFloat(s, averages, 1.0, 1e-6) // widen threshold to absorb float drift
Defensive patterns

Strategy: try-catch

Try / catch

if err := passert.EqualsFloat(s, col, expected, threshold); err != nil {
	// error lists exact values below/above expected; widen threshold or fix pipeline
	t.Fatalf("bounds assertion failed: %v", err)
}

Prevention

When it happens

Trigger: EqualsFloat assertion where one or more observed numeric values are less than (expected - threshold); e.g. float precision drift larger than the threshold, or genuinely wrong computation output.

Common situations: Floating-point unit tests with too tight a threshold; pipelines whose math differs from the expected golden values; aggregation order changing float results.

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/157711b140ac8a3c. Report an issue: GitHub.