gohugoio/hugo · error

%s operator can't be used with non-float values

Error message

%s operator can't be used with non-float values

What it means

Math operators (Add, Sub, Mul, Div, etc.) route inputs through applyOpToScalarsOrSlices -> toFloatsE. If a value cannot be converted to float64, the named operator is reported as unusable with non-float values. See math.go:292-302.

Source

Thrown at tpl/math/math.go:300

// ToRadians converts degrees into radians.
func (ns *Namespace) ToRadians(n any) (float64, error) {
	af, err := cast.ToFloat64E(n)
	if err != nil {
		return 0, errors.New("requires a numeric argument")
	}

	return af * math.Pi / 180, nil
}

func (ns *Namespace) applyOpToScalarsOrSlices(opName string, op func(x, y float64) float64, inputs ...any) (result float64, err error) {
	var i int
	var hasValue bool
	for _, input := range inputs {
		var values []float64
		var isSlice bool
		values, isSlice, err = ns.toFloatsE(input)
		if err != nil {
			err = fmt.Errorf("%s operator can't be used with non-float values", opName)
			return
		}
		hasValue = hasValue || len(values) > 0 || isSlice
		for _, value := range values {
			i++
			if i == 1 {
				result = value
				continue
			}
			result = op(result, value)
		}
	}

	if !hasValue {
		err = errMustOneNumberError
		return
	}
	return

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Ensure inputs are numeric (int/float) or numeric strings that cast.ToFloat64E accepts.
  2. Coerce with the float function or validate the value before the operation.
  3. Filter non-numeric items out of the input slice before applying the operator.

Example fix

// before
{{ math.Add .MaybeString 1 }}

// after
{{ math.Add (float .MaybeString) 1 }}
Defensive patterns

Strategy: validation

Validate before calling

// Coerce/validate operands to float64 before applying a math operator.
_, err := cast.ToFloat64E(v)
if err != nil {
    return fmt.Errorf("operand not numeric: %v", v)
}

Type guard

func isNumeric(v any) bool {
    switch v.(type) {
    case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
        return true
    }
    _, err := cast.ToFloat64E(v)
    return err == nil
}

Prevention

When it happens

Trigger: {{ math.Add "foo" 1 }} or {{ math.Mul .Title 2 }} where an operand is a non-numeric string or nil.

Common situations: Iterating over mixed-type slices; passing a string field that is sometimes non-numeric; nil values reaching a math pipeline.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/53fb13cf1ac89d3f. Report an issue: GitHub.