vitest-dev/vitest · error · AroundHookSetupError

The ` ` callback was not called in the ` ` hook. Make sure…

Error message

The `${callbackName}` callback was not called in the `${hookName}` hook. Make sure to call `${callbackName}` to run the ${hookName === 'aroundEach' ? 'test' : 'suite'}.

What it means

AroundHookSetupError thrown when an aroundEach/aroundAll hook function returns/resolves without ever calling the provided runTest/use callback. Because around hooks own the test/suite execution, skipping the callback means the inner tests never run silently. Vitest detects useCalled === false after invokeHook resolves and raises this.

Solutions

  1. Always call `await runTest()` (or `await use(value)` for the use-pattern) exactly once in the hook.
  2. Place runTest in the main flow, not behind a condition that can skip it.
  3. If using the builder fixture pattern, make sure `use(value)` is invoked.

Example fix

// before
aroundEach(async (runTest) => {
  await db.connect()
  // forgot runTest()
})

// after
aroundEach(async (runTest) => {
  await db.connect()
  await runTest()
  await db.disconnect()
})
Defensive patterns

Strategy: validation

Validate before calling

function assertAroundCallsRunTest(fnSrc: string) {
  if (!/runTest\(|use\(/.test(fnSrc)) {
    throw new Error('aroundEach body must call runTest/use')
  }
}

Try / catch

try {
  await runWithAroundHook()
} catch (e) {
  if (e instanceof AroundHookSetupError) {
    // add the missing runTest() call
  } else throw e
}

Prevention

When it happens

Trigger: Writing `aroundEach(async (runTest) => { await setup() })` and forgetting `await runTest()`; an early return before runTest; an exception swallowed before runTest is reached.

Common situations: Incomplete refactor of a beforeEach into aroundEach; conditional that skips runTest on some path; awaiting a promise that rejects and catching it without calling runTest.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/637c23b25bb37162. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/runtime/runner/run.ts:386

      // Start teardown timer after inner hooks complete - only times this hook's teardown code
      teardownTimeout = createTimeoutPromise(timeout, 'teardown', stackTraceError)

      // Signal that use() is returning (teardown phase starting)
      resolveUseReturned()
    }

    setupLimitConcurrencyRelease = await limitMaxConcurrency.acquire()

    // Start setup timeout
    setupTimeout = createTimeoutPromise(timeout, 'setup', stackTraceError)

    // Run the hook in the background
    ;(async () => {
      try {
        await invokeHook(hook, use)
        if (!useCalled) {
          throw new AroundHookSetupError(
            `The \`${callbackName}\` callback was not called in the \`${hookName}\` hook. `
            + `Make sure to call \`${callbackName}\` to run the ${hookName === 'aroundEach' ? 'test' : 'suite'}.`,
          )
        }
        resolveHookComplete()
      }
      catch (error) {
        rejectHookComplete(error as Error)
      }
      finally {
        setupLimitConcurrencyRelease?.()
        teardownLimitConcurrencyRelease?.()
      }
    })()

    // Wait for either: use() to be called OR hook to complete (error) OR setup timeout
    try {
      await Promise.race([

View on GitHub (pinned to 1fa9837ec2)