stretchr/testify · error

'Require' must not be called before 'Run' or 'SetT'

Error message

'Require' must not be called before 'Run' or 'SetT'

What it means

suite.Require() (suite/suite.go:57-64) returns the per-suite *require.Assertions handle, which is only allocated inside SetT (suite.go:42-48). The library panics with this message when Require() is invoked on a suite whose SetT has never run, because returning a nil *require.Assertions would just defer the failure to a nil-pointer deref deeper in the test. The panic pins the misuse to the exact call site and tells the author the suite lifecycle wasn't entered.

Solutions

  1. Drive the suite through the framework entrypoint: call suite.Run(t, &MySuite{}) once in your top-level TestXxx, and let it invoke SetupSuite/SetupTest/Test*/TearDown — by the time those run, SetT has executed and Require() is safe.
  2. If you construct the suite yourself, call s.SetT(t) explicitly before any Require()/Assert() use.
  3. Always pass a pointer (&MySuite{}) to suite.Run; embedding suite.Suite by value plus copying will leave require nil on the copy.
  4. Move any Require()/Assert() calls out of goroutines spawned before SetT, or pass the already-initialized suite by pointer into the goroutine.

Example fix

// before
func TestFoo(t *testing.T) {
    s := &MySuite{}
    s.SetupSuite()        // user-invoked; SetT never ran
    s.Require().Equal(1, 1) // panic: Require before Run/SetT
}

// after
func TestFoo(t *testing.T) {
    suite.Run(t, &MySuite{}) // SetT runs first; Require() safe inside SetupSuite/Test*
}
// inside the suite:
func (s *MySuite) SetupSuite() { s.Require().Equal(1, 1) }
Defensive patterns

Strategy: validation

Validate before calling

// Guard before calling Require() on a suite whose lifecycle you don't control.
func safeRequire(s *suite.Suite) (*require.Assertions, error) {
    // Suite.require is private; the only public signal is T().
    if s.T() == nil {
        return nil, errors.New("suite not initialized: call suite.Run or SetT first")
    }
    return s.Require(), nil
}

Type guard

// Type-narrow on the suite interface rather than guarding Require each time:
// only enter suite-internal helpers when the framework has set T.
func suiteReady(s TestingSuite) bool {
    type tGetter interface{ T() *testing.T }
    g, ok := s.(tGetter)
    return ok && g.T() != nil
}

// usage: if !suiteReady(s) { t.Skip("suite not run via suite.Run") }

Try / catch

// Convert the panic into a test failure at a controlled boundary.
func safeRequireCall(t *testing.T, s *MySuite, fn func(*require.Assertions)) {
    defer func() {
        if r := recover(); r != nil {
            t.Fatalf("Require misuse: %v\nEnsure the suite is started with suite.Run(t, &MySuite{}).", r)
        }
    }()
    fn(s.Require())
}

Prevention

When it happens

Trigger: Calling suite.Require() (or this.Require() from an embedded Suite) before suite.Run(t, &s) or an explicit SetT(t) has executed. Concretely: (a) constructing &MySuite{} and calling its methods in a plain func(t *testing.T) without suite.Run; (b) calling Require() inside SetupSuite/SetupTest of a suite that was registered via t.Run(...) instead of suite.Run(t, ...); (c) calling Require() from a goroutine spawned in BeforeTest that races ahead of SetT, or after manually zeroing the suite; (d) embedding *suite.Suite by value and copying it before Run wires the receiver.

Common situations: Migrating a flat *testing.T test to the suite model and forgetting to swap t.Run for suite.Run; subtest registered via t.Run(name, s.MyTest) reading suite.Require() inside MyTest; refactoring SetupAllSuite logic into a helper invoked from TestMain where no T exists; copying a suite struct value instead of passing a pointer (SetT mutates the receiver, so a copy stays uninitialized).

Related errors


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

Appendix: source

Thrown at suite/suite.go:61

	suite.mu.Lock()
	defer suite.mu.Unlock()
	suite.t = t
	suite.Assertions = assert.New(t)
	suite.require = require.New(t)
}

// SetS needs to set the current test suite as parent
// to get access to the parent methods
func (suite *Suite) SetS(s TestingSuite) {
	suite.s = s
}

// Require returns a require context for suite.
func (suite *Suite) Require() *require.Assertions {
	suite.mu.Lock()
	defer suite.mu.Unlock()
	if suite.require == nil {
		panic("'Require' must not be called before 'Run' or 'SetT'")
	}
	return suite.require
}

// Assert returns an assert context for suite. Normally, you can call:
//
//	suite.NoError(err)
//
// But for situations where the embedded methods are overridden (for example,
// you might want to override assert.Assertions with require.Assertions), this
// method is provided so you can call:
//
//	suite.Assert().NoError(err)
func (suite *Suite) Assert() *assert.Assertions {
	suite.mu.Lock()
	defer suite.mu.Unlock()
	if suite.Assertions == nil {
		panic("'Assert' must not be called before 'Run' or 'SetT'")

View on GitHub (pinned to 001eb7946b)