stretchr/testify · error
assert: arguments: %s is not a func
Error message
assert: arguments: %s is not a func
What it means
Panicked by MatchedBy() (mock/mock.go:921) when reflect.TypeOf(fn).Kind() != reflect.Func. MatchedBy builds an argumentMatcher that invokes fn against each call argument, so a non-function input is a programming error. The check is at mock/mock.go:924.
Source
Thrown at mock/mock.go:925
}
// MatchedBy can be used to match a mock call based on only certain properties
// from a complex struct or some calculation. It takes a function that will be
// evaluated with the called argument and will return true when there's a match
// and false otherwise.
//
// Example:
//
// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
//
// fn must be a function accepting a single argument (of the expected type)
// which returns a bool. If fn doesn't match the required signature,
// MatchedBy() panics.
func MatchedBy(fn interface{}) argumentMatcher {
fnType := reflect.TypeOf(fn)
if fnType.Kind() != reflect.Func {
panic(fmt.Sprintf("assert: arguments: %s is not a func", fn))
}
if fnType.NumIn() != 1 {
panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn))
}
if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool {
panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn))
}
return argumentMatcher{fn: reflect.ValueOf(fn)}
}
// Get Returns the argument at the specified index.
func (args Arguments) Get(index int) interface{} {
if index+1 > len(args) {
panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args)))
}
return args[index]
}View on GitHub (pinned to 001eb7946b)
Solutions
- Pass a function literal: mock.MatchedBy(func(x ExpectedType) bool { ... }).
- Verify the variable passed to MatchedBy is actually a func with reflect.TypeOf(v).Kind() == reflect.Func.
- If you meant to match a value, use the literal value directly in Mock.On instead of MatchedBy.
Example fix
// before
m.On("Set", mock.MatchedBy(value)).Return(nil)
// after
m.On("Set", mock.MatchedBy(func(v int) bool { return v > 0 })).Return(nil) Defensive patterns
Strategy: type-guard
Validate before calling
func isFunc(v interface{}) bool {
if v == nil { return false }
return reflect.TypeOf(v).Kind() == reflect.Func
}
// before MatchedBy: assert.True(t, isFunc(matcher)) Type guard
func isFunc(v interface{}) bool {
if v == nil { return false }
return reflect.TypeOf(v).Kind() == reflect.Func
} Try / catch
// Only call MatchedBy when the input is a func:
if isFunc(matcher) {
m.On("Do", mock.MatchedBy(matcher))
} Prevention
- Always pass a function literal to MatchedBy, not a variable of unknown kind.
- Add a unit test for your matcher-builder that asserts the result is a func.
When it happens
Trigger: Calling mock.MatchedBy(someStruct{}) or mock.MatchedBy(42) — passing anything other than a function. Typically a typo where the matcher predicate was forgotten.
Common situations: Refactoring that replaces a func with a struct method reference incorrectly; copy-paste errors; passing a method value that resolved to nil interface.
Related errors
- cannot use Func in expectations. Use mock.AnythingOfType("%T
- assert: arguments: %s does not take exactly one argument
- assert: arguments: %s does not return a bool
- not before calls must be created with Mock.On()
- assert: arguments: Cannot call Get(%d) because there are %d
AI-assisted analysis of stretchr/testify@001eb7946b (2026-08-04).
Data as JSON: /data/errors/0a33c27bd313ad89.json.
Report an issue: GitHub.