stretchr/testify · error

assert: arguments: %s does not take exactly one argument

Error message

assert: arguments: %s does not take exactly one argument

What it means

Panicked by MatchedBy() (mock/mock.go:921) when the passed function's reflect.Type reports NumIn() != 1. MatchedBy calls fn with exactly one argument (the mocked call argument at that position), so a zero- or multi-arg function is invalid. Check at mock/mock.go:927.

Source

Thrown at mock/mock.go:928

// 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]
}

// Is gets whether the objects match the arguments specified.
func (args Arguments) Is(objects ...interface{}) bool {

View on GitHub (pinned to 001eb7946b)

Solutions

  1. Ensure the matcher function takes exactly one argument: mock.MatchedBy(func(singleArg T) bool { ... }).
  2. If you need multiple values, match on a struct/struct-pointer argument that bundles them.
  3. Wrap an existing multi-arg predicate in a single-arg closure that unpacks the fields.

Example fix

// before
m.On("Do", mock.MatchedBy(func(a, b int) bool { return a+b > 0 })).Return(nil)
// after
m.On("Do", mock.MatchedBy(func(p Pair) bool { return p.A+p.B > 0 })).Return(nil)
Defensive patterns

Strategy: validation

Validate before calling

func takesOneArg(fn interface{}) bool {
    t := reflect.TypeOf(fn)
    return t != nil && t.Kind() == reflect.Func && t.NumIn() == 1
}
// before MatchedBy: assert.True(t, takesOneArg(matcher))

Type guard

func matcherTakesOneArg(fn interface{}) bool {
    t := reflect.TypeOf(fn)
    return t != nil && t.Kind() == reflect.Func && t.NumIn() == 1
}

Try / catch

// Validate arity before constructing the matcher:
if !matcherTakesOneArg(matcher) {
    log.Fatal("matcher must take exactly one argument")
}
m.On("Do", mock.MatchedBy(matcher))

Prevention

When it happens

Trigger: Calling mock.MatchedBy(func(a, b int) bool { ... }) or mock.MatchedBy(func() bool { ... }) — a predicate with the wrong arity.

Common situations: Reusing an existing two-argument predicate function as a matcher; refactoring a matcher's signature and forgetting it must take exactly one parameter.

Related errors


AI-assisted analysis of stretchr/testify@001eb7946b (2026-08-04). Data as JSON: /data/errors/57457e2ab24a14c9.json. Report an issue: GitHub.