{"id":"043d456776da15e9","repo":"stretchr/testify","slug":"parameters-must-be-numerical","errorCode":null,"errorMessage":"Parameters must be numerical","messagePattern":"Parameters must be numerical","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"assert/assertions.go","lineNumber":1558,"sourceCode":"\t\tif !InDelta(\n\t\t\tt,\n\t\t\tev.Interface(),\n\t\t\tav.Interface(),\n\t\t\tdelta,\n\t\t\tmsgAndArgs...,\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc calcRelativeError(expected, actual interface{}) (float64, error) {\n\taf, aok := toFloat(expected)\n\tbf, bok := toFloat(actual)\n\tif !aok || !bok {\n\t\treturn 0, fmt.Errorf(\"Parameters must be numerical\")\n\t}\n\tif math.IsNaN(af) && math.IsNaN(bf) {\n\t\treturn 0, nil\n\t}\n\tif math.IsNaN(af) {\n\t\treturn 0, errors.New(\"expected value must not be NaN\")\n\t}\n\tif af == 0 {\n\t\treturn 0, fmt.Errorf(\"expected value must have a value other than zero to calculate the relative error\")\n\t}\n\tif math.IsNaN(bf) {\n\t\treturn 0, errors.New(\"actual value must not be NaN\")\n\t}\n\n\treturn math.Abs(af-bf) / math.Abs(af), nil\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon","sourceCodeStart":1540,"sourceCodeEnd":1576,"githubUrl":"https://github.com/stretchr/testify/blob/001eb7946baf451879253643e4ce4b38eaa0d4a7/assert/assertions.go#L1540-L1576","documentation":"Returned by calcRelativeError (assert/assertions.go:1554) when either toFloat(expected) or toFloat(actual) returns false. toFloat (assert/assertions.go:1413) only accepts numeric kinds (int/uint/float variants) and time.Duration; anything else (string, struct, bool, slice) fails. The error surfaces via assert.InEpsilon which calls calcRelativeError.","triggerScenarios":"Calling assert.InEpsilon(t, expected, actual, epsilon) or assert.InEpsilonSlice where expected or actual is a string, struct, bool, or any non-numeric type. Also triggered by passing a numeric wrapped in an interface{} that lost its concrete numeric type.","commonSituations":"Asserting tolerance on values read from JSON/JSON-unmarshaled into interface{} (which become float64 but may be string-encoded numbers), or comparing parsed config values that arrived as strings.","solutions":["Convert both operands to a numeric type (float64/int) before passing them to InEpsilon.","If the value comes from JSON, unmarshal into a typed float64 variable rather than interface{}.","Switch to assert.Equal if exact comparison is acceptable and the value is non-numeric."],"exampleFix":"// before\nassert.InEpsilon(t, jsonVal, expected, 0.01) // jsonVal is interface{}\n// after\nf, _ := jsonVal.(float64)\nassert.InEpsilon(t, f, expected, 0.01)","handlingStrategy":"type-guard","validationCode":"func isNumeric(v interface{}) bool {\n    switch v.(type) {\n    case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, time.Duration:\n        return true\n    }\n    return false\n}\n// before InEpsilon:\nif !isNumeric(expected) || !isNumeric(actual) { t.Fatal(\"non-numeric\") }","typeGuard":"func isNumeric(v interface{}) bool {\n    switch v.(type) {\n    case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, time.Duration:\n        return true\n    }\n    return false\n}","tryCatchPattern":"// Validate types before the call (Go returns this as error via Fail, not panic):\nif !isNumeric(expected) || !isNumeric(actual) {\n    t.Fatalf(\"InEpsilon needs numeric args, got %T, %T\", expected, actual)\n}\nassert.InEpsilon(t, expected, actual, eps)","preventionTips":["Always unmarshal JSON into typed float64 fields, not interface{}.","Wrap InEpsilon calls in a helper that type-checks operands first.","Document expected numeric types in test fixtures."],"tags":["assertion","numeric","in-epsilon","type-coercion"],"analyzedSha":"001eb7946baf451879253643e4ce4b38eaa0d4a7","analyzedAt":"2026-08-04T21:49:58.715Z","schemaVersion":2}