{"record":{"id":"53fb13cf1ac89d3f","repo":"gohugoio/hugo","slug":"s-operator-can-t-be-used-with-non-float-values","errorCode":null,"errorMessage":"%s operator can't be used with non-float values","messagePattern":"(.+?) operator can't be used with non-float values","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/math/math.go","lineNumber":300,"sourceCode":"// ToRadians converts degrees into radians.\nfunc (ns *Namespace) ToRadians(n any) (float64, error) {\n\taf, err := cast.ToFloat64E(n)\n\tif err != nil {\n\t\treturn 0, errors.New(\"requires a numeric argument\")\n\t}\n\n\treturn af * math.Pi / 180, nil\n}\n\nfunc (ns *Namespace) applyOpToScalarsOrSlices(opName string, op func(x, y float64) float64, inputs ...any) (result float64, err error) {\n\tvar i int\n\tvar hasValue bool\n\tfor _, input := range inputs {\n\t\tvar values []float64\n\t\tvar isSlice bool\n\t\tvalues, isSlice, err = ns.toFloatsE(input)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"%s operator can't be used with non-float values\", opName)\n\t\t\treturn\n\t\t}\n\t\thasValue = hasValue || len(values) > 0 || isSlice\n\t\tfor _, value := range values {\n\t\t\ti++\n\t\t\tif i == 1 {\n\t\t\t\tresult = value\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresult = op(result, value)\n\t\t}\n\t}\n\n\tif !hasValue {\n\t\terr = errMustOneNumberError\n\t\treturn\n\t}\n\treturn","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/math/math.go#L282-L318","documentation":"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.","triggerScenarios":"{{ math.Add \"foo\" 1 }} or {{ math.Mul .Title 2 }} where an operand is a non-numeric string or nil.","commonSituations":"Iterating over mixed-type slices; passing a string field that is sometimes non-numeric; nil values reaching a math pipeline.","solutions":["Ensure inputs are numeric (int/float) or numeric strings that cast.ToFloat64E accepts.","Coerce with the float function or validate the value before the operation.","Filter non-numeric items out of the input slice before applying the operator."],"exampleFix":"// before\n{{ math.Add .MaybeString 1 }}\n\n// after\n{{ math.Add (float .MaybeString) 1 }}","handlingStrategy":"validation","validationCode":"// Coerce/validate operands to float64 before applying a math operator.\n_, err := cast.ToFloat64E(v)\nif err != nil {\n    return fmt.Errorf(\"operand not numeric: %v\", v)\n}","typeGuard":"func isNumeric(v any) bool {\n    switch v.(type) {\n    case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:\n        return true\n    }\n    _, err := cast.ToFloat64E(v)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Pipe values through the float function when their type is uncertain.","Filter non-numeric entries from slices before applying math operators."],"tags":["hugo","math","numeric","template","type-coercion"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}