{"id":"637c23b25bb37162","repo":"vitest-dev/vitest","slug":"the-callbackname-callback-was-not-called-in-t","errorCode":null,"errorMessage":"The `${callbackName}` callback was not called in the `${hookName}` hook. Make sure to call `${callbackName}` to run the ${hookName === 'aroundEach' ? 'test' : 'suite'}.","messagePattern":"The `(.+?)` callback was not called in the `(.+?)` hook\\. Make sure to call `(.+?)` to run the (.+?)\\.","errorType":"exception","errorClass":"AroundHookSetupError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/runtime/runner/run.ts","lineNumber":386,"sourceCode":"\n      // Start teardown timer after inner hooks complete - only times this hook's teardown code\n      teardownTimeout = createTimeoutPromise(timeout, 'teardown', stackTraceError)\n\n      // Signal that use() is returning (teardown phase starting)\n      resolveUseReturned()\n    }\n\n    setupLimitConcurrencyRelease = await limitMaxConcurrency.acquire()\n\n    // Start setup timeout\n    setupTimeout = createTimeoutPromise(timeout, 'setup', stackTraceError)\n\n    // Run the hook in the background\n    ;(async () => {\n      try {\n        await invokeHook(hook, use)\n        if (!useCalled) {\n          throw new AroundHookSetupError(\n            `The \\`${callbackName}\\` callback was not called in the \\`${hookName}\\` hook. `\n            + `Make sure to call \\`${callbackName}\\` to run the ${hookName === 'aroundEach' ? 'test' : 'suite'}.`,\n          )\n        }\n        resolveHookComplete()\n      }\n      catch (error) {\n        rejectHookComplete(error as Error)\n      }\n      finally {\n        setupLimitConcurrencyRelease?.()\n        teardownLimitConcurrencyRelease?.()\n      }\n    })()\n\n    // Wait for either: use() to be called OR hook to complete (error) OR setup timeout\n    try {\n      await Promise.race([","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/runtime/runner/run.ts#L368-L404","documentation":"If an `aroundEach`/`aroundAll` hook function returns/resolves without ever calling the provided `runTest`/`runSuite` callback, `callAroundHooks` detects that `useCalled` is still false after the hook completes and throws an `AroundHookSetupError` (run.ts:385-390). The hook must invoke the callback so the inner tests/suite actually run.","triggerScenarios":"An `aroundEach` hook that forgets to call `runTest()`; an `aroundAll` hook that returns early before `runSuite()`; an awaited condition that throws/swallows before reaching the callback call.","commonSituations":"Forgetting the callback after refactoring; conditional logic that skips the call on some path; early return/throw that bypasses runTest.","solutions":["Ensure every code path in the around hook calls `runTest`/`runSuite` exactly once.","Place the callback call on the unconditional main path, before teardown.","If the hook should skip the test/suite, use skip mechanisms instead of omitting the call."],"exampleFix":"// before\naroundEach(async (runTest) => {\n  await setup()\n  // forgot to call runTest()\n})\n// after\naroundEach(async (runTest) => {\n  await setup()\n  await runTest()\n  await teardown()\n})","handlingStrategy":"validation","validationCode":"// Static reminder: every aroundEach/aroundAll must contain a runTest()/runSuite() call.\n// Use a lint rule requiring the callback name to appear at least once in the hook body.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always call runTest/runSuite exactly once on the main path.","Avoid early returns before the callback.","If skipping, use ctx.skip() or test.skip instead of omitting the call."],"tags":["hooks","aroundeach","aroundall","lifecycle"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}