stretchr/testify · error
Parameters must be numerical
Error message
Parameters must be numerical
What it means
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.
Source
Thrown at assert/assertions.go:1558
if !InDelta(
t,
ev.Interface(),
av.Interface(),
delta,
msgAndArgs...,
) {
return false
}
}
return true
}
func calcRelativeError(expected, actual interface{}) (float64, error) {
af, aok := toFloat(expected)
bf, bok := toFloat(actual)
if !aok || !bok {
return 0, fmt.Errorf("Parameters must be numerical")
}
if math.IsNaN(af) && math.IsNaN(bf) {
return 0, nil
}
if math.IsNaN(af) {
return 0, errors.New("expected value must not be NaN")
}
if af == 0 {
return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error")
}
if math.IsNaN(bf) {
return 0, errors.New("actual value must not be NaN")
}
return math.Abs(af-bf) / math.Abs(af), nil
}
// InEpsilon asserts that expected and actual have a relative error less than epsilonView on GitHub (pinned to 001eb7946b)
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.
Example fix
// before
assert.InEpsilon(t, jsonVal, expected, 0.01) // jsonVal is interface{}
// after
f, _ := jsonVal.(float64)
assert.InEpsilon(t, f, expected, 0.01) Defensive patterns
Strategy: type-guard
Validate before calling
func isNumeric(v interface{}) bool {
switch v.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, time.Duration:
return true
}
return false
}
// before InEpsilon:
if !isNumeric(expected) || !isNumeric(actual) { t.Fatal("non-numeric") } Type guard
func isNumeric(v interface{}) bool {
switch v.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, time.Duration:
return true
}
return false
} Try / catch
// Validate types before the call (Go returns this as error via Fail, not panic):
if !isNumeric(expected) || !isNumeric(actual) {
t.Fatalf("InEpsilon needs numeric args, got %T, %T", expected, actual)
}
assert.InEpsilon(t, expected, actual, eps) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- expected value must not be NaN
- expected value must have a value other than zero to calculat
- actual value must not be NaN
- cannot take func type as argument
AI-assisted analysis of stretchr/testify@001eb7946b (2026-08-04).
Data as JSON: /data/errors/043d456776da15e9.json.
Report an issue: GitHub.