vitest-dev/vitest · error · TypeError
`bench()` does not accept options as the third argument…
Error message
`bench()` does not accept options as the third argument. Pass options as the second argument instead: `bench(name, options, fn)`.
What it means
`bench(name, fn)` and `bench(name, options, fn)` are the only valid call shapes. There is no `bench(name, fn, options)` form. This `TypeError` fires when the second argument (`a`) is a function AND a third argument (`b`) is provided — Vitest infers the user put options in the wrong slot.
Solutions
- Reorder to `bench(name, options, fn)`.
- If you do not need options, call `bench(name, fn)` with two arguments only.
Example fix
// before
bench('sort', sortFn, { iterations: 100 })
// after
bench('sort', { iterations: 100 }, sortFn) Defensive patterns
Strategy: validation
Validate before calling
if (typeof a === 'function' && b !== undefined) throw new TypeError('move options to 2nd arg: bench(name, options, fn)') Type guard
null
Try / catch
null
Prevention
- Memorize the two valid signatures: `bench(name, fn)` and `bench(name, options, fn)`.
- Use TypeScript overloads — they enforce the order at compile time.
- Run `pnpm lint` to catch argument-order mistakes early.
When it happens
Trigger: Calling `bench('x', fn, { iterations: 100 })` — here `a = fn` (function) and `b = { iterations: 100 }` is defined, triggering the check at benchmark.ts:572-575. The valid form swaps the last two: `bench('x', { iterations: 100 }, fn)`.
Common situations: Muscle memory from `test(name, fn, timeout)` (Jest-style) where options/timeout come last; migrating from a library whose signature is `(name, fn, opts)`; autocomplete inserting options in the wrong position.
Related errors
- `bench()` expects a benchmark function. Call `bench(name…
- `bench.from()` expects a string path or a function…
- `bench.from()` requires a name (string or named function)…
- `bench.compare()` expects every argument to be the return…
- `bench.compare()` requires at least 2 benchmarks, received
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/bac948dff8b41bf2.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/benchmark.ts:574
}
return bench
}
function formatModuleId(moduleId: string, root: string): string {
if (!root || !isAbsolute(moduleId)) {
return moduleId
}
return relative(root, moduleId)
}
function normalizeBenchArgs(
a: BenchFn | BenchFnOptions,
b: BenchFn | BenchFnOptions | undefined,
): { fn: BenchFn; fnOpts: BenchOptions | undefined; writeResult: string | undefined; perProject: boolean } {
if (typeof a === 'function') {
if (b !== undefined) {
throw new TypeError('`bench()` does not accept options as the third argument. Pass options as the second argument instead: `bench(name, options, fn)`.')
}
return { fn: a, fnOpts: undefined, writeResult: undefined, perProject: false }
}
if (typeof b !== 'function') {
throw new TypeError('`bench()` expects a benchmark function. Call `bench(name, fn)` or `bench(name, options, fn)`.')
}
// 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,View on GitHub (pinned to 1fa9837ec2)