vitest-dev/vitest · error · Error

Calling the test function inside another test function is…

Error message

Calling the test function inside another test function is not allowed. Please put it inside "describe" or "suite" so it can be properly collected.

What it means

Thrown by the test() API when getCurrentTest() returns a truthy value, i.e., test() is invoked while another test's body is executing. Vitest collects tests statically (at describe/suite scope); nested runtime calls would produce tasks after collection closed, so they are rejected. Tests must live at the top level or inside describe/suite factories.

Solutions

  1. Move nested test() calls out to the describe/suite or top level.
  2. Generate dynamic tests at module top-level or inside describe, not inside test bodies.
  3. For data-driven tests, use it.each / test.each at collection time.

Example fix

// before
test('outer', () => {
  test('inner', () => {}) // throws
})

// after
describe('group', () => {
  test('outer', () => {})
  test('inner', () => {})
})
Defensive patterns

Strategy: validation

Validate before calling

import { getCurrentTest } from 'vitest'
function defineTest(name: string, fn: () => void) {
  if (getCurrentTest()) throw new Error('do not nest test() calls')
  return test(name, fn)
}

Type guard

const atTopLevel = () => !getCurrentTest()

Prevention

When it happens

Trigger: Writing `test('outer', () => { test('inner', () => {}) })`; calling a helper that itself calls test() from within a test body; conditionally defining tests at runtime inside a test.

Common situations: Migrating from frameworks that allow runtime test definition; generating tests dynamically inside a loop that runs during a test instead of during collection; helper functions misused as test bodies.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/runner/suite.ts:114

 * test('should add two numbers', () => {
 *   expect(add(1, 2)).toBe(3);
 * });
 * ```
 * @example
 * ```ts
 * // Define a test with options
 * test('should subtract two numbers', { retry: 3 }, () => {
 *   expect(subtract(5, 2)).toBe(3);
 * });
 * ```
 */
export const test: TestAPI = createTest(function (
  name: string | Function,
  optionsOrFn?: TestOptions | TestFunction,
  optionsOrTest?: number | TestOptions | TestFunction,
) {
  if (getCurrentTest()) {
    throw new Error(
      'Calling the test function inside another test function is not allowed. Please put it inside "describe" or "suite" so it can be properly collected.',
    )
  }

  getCurrentSuite().test.fn.call(
    this,
    formatName(name),
    optionsOrFn as TestOptions,
    optionsOrTest as TestFunction,
  )
})

/**
 * Creates a suite of tests, allowing for grouping and hierarchical organization of tests.
 * Suites can contain both tests and other suites, enabling complex test structures.
 *
 * @param {string} name - The name of the suite, used for identification and reporting.
 * @param {Function} fn - A function that defines the tests and suites within this suite.

View on GitHub (pinned to 1fa9837ec2)