stretchr/testify · error
test failed and t is missing `FailNow()`
Error message
test failed and t is missing `FailNow()`
What it means
Panicked by FailNow (assert/assertions.go:346) when the passed TestingT does not implement the failNower interface (i.e. lacks a FailNow() method). The TestingT interface could not be extended with FailNow without breaking backwards compatibility (issue #263), so testify falls back to a panic. This typically surfaces when require-package assertions are used against a custom testing double that only implements Errorf/Logf.
Source
Thrown at assert/assertions.go:361
}
// FailNow fails test
func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
Fail(t, failureMessage, msgAndArgs...)
// We cannot extend TestingT with FailNow() and
// maintain backwards compatibility, so we fallback
// to panicking when FailNow is not available in
// TestingT.
// See issue #263
if t, ok := t.(failNower); ok {
t.FailNow()
} else {
panic("test failed and t is missing `FailNow()`")
}
return false
}
// Fail reports a failure through
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
content := []labeledContent{
{"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
{"Error", failureMessage},
}
// Add test name if the Go version supports it
if n, ok := t.(interface {
Name() string
}); ok {View on GitHub (pinned to 001eb7946b)
Solutions
- Make your custom TestingT implement FailNow() (delegating to embedded *testing.T or calling runtime.Goexit).
- Use assert.* (which only needs Errorf) instead of require.* when your fake lacks FailNow.
- Embed *testing.T in your wrapper so it inherits FailNow for free.
Example fix
// before
type myT struct{ log bytes.Buffer }
func (m *myT) Errorf(f string, a ...any) { /* ... */ }
// require.True(myT{}, x) -> panic
// after
func (m *myT) FailNow() { runtime.Goexit() } Defensive patterns
Strategy: type-guard
Validate before calling
func implementsFailNow(t assert.TestingT) bool {
_, ok := t.(interface{ FailNow() })
return ok
}
// before require.X: assert.True(t, implementsFailNow(tt)) Type guard
func hasFailNow(t assert.TestingT) bool {
_, ok := t.(interface{ FailNow() })
return ok
} Try / catch
// Either implement FailNow or fall back to assert.*:
if !hasFailNow(tt) {
assert.True(tt, cond) // assert.* needs only Errorf
} else {
require.True(tt, cond)
} Prevention
- Always embed *testing.T in custom test doubles to inherit FailNow.
- Prefer assert.* over require.* when the TestingT is a fake/minimal type.
- Document the FailNow requirement on any helper accepting TestingT.
When it happens
Trigger: Passing a custom TestingT (e.g. a fake test reporter, a *bytes.Buffer wrapper, or a third-party test harness) to assert.FailNow or any require.* function, where that type implements Errorf but not FailNow. Also passing a plain *testing.TB value at the interface level in an older code path.
Common situations: Using require inside a custom assertion helper that accepts a minimal interface; wrapping *testing.T in a struct that forwards Errorf but forgets FailNow; using testify with a non-testing.T test runner (e.g. Ginkgo or a custom harness).
Related errors
- Reset() is deprecated
- Copy() is deprecated
- cannot use Func in expectations. Use mock.AnythingOfType("%T
- not before calls must be created with Mock.On()
- assert: arguments: %s is not a func
AI-assisted analysis of stretchr/testify@001eb7946b (2026-08-04).
Data as JSON: /data/errors/c98d46fb286c705f.json.
Report an issue: GitHub.