vitest-dev/vitest · error · Error

Cannot use the `bench` test-context fixture within a regular

Error message

Cannot use the `bench` test-context fixture within a regular test run. Benchmarks are inherently flaky, so Vitest runs them in a dedicated project based on the `benchmark.include` pattern (default `**/*.{bench,benchmark}.?(c|m)[jt]s?(x)`). Move this code to a file matched by `benchmark.include`, and make sure `bench` is destructured from the test context (`test('...', async ({ bench }) => { ... })`) — it is not a top-level export of `vitest`. See https://vitest.dev/guide/benchmarking#stability

What it means

Benchmarks are noisy, so Vitest runs them in a dedicated project matched by `benchmark.include` (default `**/*.{bench,benchmark}.?(c|m)[jt]s?(x)`) rather than in regular test runs. `validateBenchmarkProject` (`benchmark.ts:599`) throws when `config.benchmark.enabled` is false — i.e. the `bench` fixture is used in a non-benchmark run. `bench` is a test-context fixture (`async ({ bench }) => ...`), NOT a top-level export of `vitest`.

Source

Thrown at packages/vitest/src/runtime/benchmark.ts:599

  // Strip vitest-specific fields only when present so we don't allocate a new
  // object — preserving referential identity matters: users inspect
  // `registration.fnOpts` and the provider sees the same object the caller
  // passed in.
  if (a.writeResult === undefined && a.perProject === undefined) {
    return { fn: b, fnOpts: a as BenchOptions, writeResult: undefined, perProject: false }
  }
  const { writeResult, perProject, ...fnOpts } = a
  return {
    fn: b,
    fnOpts: Object.keys(fnOpts).length > 0 ? fnOpts as BenchOptions : undefined,
    writeResult,
    perProject: perProject ?? false,
  }
}

function validateBenchmarkProject(config: SerializedConfig) {
  if (!config.benchmark.enabled) {
    throw new Error(
      `Cannot use the \`bench\` test-context fixture within a regular test run. `
      + `Benchmarks are inherently flaky, so Vitest runs them in a dedicated project based on the \`benchmark.include\` pattern (default \`**/*.{bench,benchmark}.?(c|m)[jt]s?(x)\`). `
      + `Move this code to a file matched by \`benchmark.include\`, and make sure \`bench\` is destructured from the test context (\`test('...', async ({ bench }) => { ... })\`) — it is not a top-level export of \`vitest\`. `
      + `See https://vitest.dev/guide/benchmarking#stability`,
    )
  }
}

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Rename the file to `*.bench.ts` (or whatever matches `benchmark.include`).
  2. Access `bench` via the test context: `test('...', async ({ bench }) => { ... })` — never as a top-level import.
  3. Ensure a benchmark project exists (define one with `test.benchmark` in the config) and run with `--project <name>` if needed.

Example fix

// before (utils.test.ts) — regular test file
import { test } from 'vitest'
test('sort speed', () => {
  bench('sort', () => sortArr()) // bench not available here
})

// after (sort.bench.ts) — file matches benchmark.include
test('sort speed', async ({ bench }) => {
  bench('sort', () => sortArr())
})
Defensive patterns

Strategy: validation

Validate before calling

// Gate benchmark code on whether benchmarks are enabled for this run.
// Easiest signal: the file extension matches benchmark.include.
const isBenchFile = /\.(bench|benchmark)\.[mc]?[tj]sx?$/.test(__filename ?? '')
if (!isBenchFile) {
  throw new Error('Move this benchmark into a *.bench.ts file')
}
// And always destructure bench from the context:
test('x', async ({ bench }) => { /* ... */ })

Prevention

When it happens

Trigger: Importing `{ bench }` from `'vitest'` in a regular `.test.ts` file; destructuring `bench` from the context inside a file not matched by `benchmark.include`; running a `.bench.ts` file via the normal test command without a benchmark project configured.

Common situations: Writing benchmarks in a normal test file; top-level `import { bench } from 'vitest'`; missing a benchmark project in the config; running with `--project` pointing at a non-benchmark project.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/e253a42df00e7cbf.json. Report an issue: GitHub.