hashicorp/terraform · error

can't compute sum of opposing infinities

Error message

can't compute sum of opposing infinities

What it means

sum() function error: summing numbers produced an opposing-infinity result (+Inf + -Inf), which Go's big.Float.Add signals by panicking with big.ErrNaN. The deferred recover catches that specific panic type and converts it to this controlled error; any other panic is re-thrown. This keeps the cty Function abstraction panic-free.

Solutions

  1. Filter or clamp infinities before summing (e.g. exclude infinite values with a for-expression).
  2. Trace which upstream computation yields +/-Inf and fix the root cause (often a divide by zero).
  3. Replace infinite values with large finite bounds if approximation is acceptable.

Example fix

// before
locals { total = sum([var.a, var.b]) } # a=+Inf, b=-Inf

// after
locals { total = sum([for v in [var.a, var.b] : v if v != math.inf && v != -math.inf]) }
Defensive patterns

Strategy: validation

Validate before calling

// Filter infinities before summing.
locals {
  finite = [for v in var.nums : v if v != "Infinity" && v != "-Infinity"]
  total  = sum(local.finite)
}

Prevention

When it happens

Trigger: Calling sum() on a list containing both positive and negative infinity (e.g. [math.inf, -math.inf] equivalent cty values), so big.Float.Add panics with ErrNaN.

Common situations: Computed values derived from division-by-zero producing +/-Inf and then aggregated with sum(); data pipelines that mix unbounded-positive and unbounded-negative signals.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/9e89d740edf4d7fa. Report an issue: GitHub.

Appendix: source

Thrown at internal/lang/funcs/collection.go:532

		arg := args[0].AsValueSlice()
		ty := args[0].Type()

		if !ty.IsListType() && !ty.IsSetType() && !ty.IsTupleType() {
			return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple. Received %s", ty.FriendlyName())
		}

		if !args[0].IsWhollyKnown() {
			return cty.UnknownVal(cty.Number), nil
		}

		// big.Float.Add can panic if the input values are opposing infinities,
		// so we must catch that here in order to remain within
		// the cty Function abstraction.
		defer func() {
			if r := recover(); r != nil {
				if _, ok := r.(big.ErrNaN); ok {
					ret = cty.NilVal
					err = fmt.Errorf("can't compute sum of opposing infinities")
				} else {
					// not a panic we recognize
					panic(r)
				}
			}
		}()

		s := arg[0]
		if s.IsNull() {
			return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")
		}
		s, err = convert.Convert(s, cty.Number)
		if err != nil {
			return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")
		}
		for _, v := range arg[1:] {
			if v.IsNull() {
				return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")

View on GitHub (pinned to d32a084675)