vitest-dev/vitest · error · SyntaxError
`bench.compare()` requires at least 2 benchmarks, received $
Error message
`bench.compare()` requires at least 2 benchmarks, received ${registrations.length} instead. ${registrations.length === 1 ? 'Consider calling `bench().run()`. ' : 'Define benchmarks by calling `bench()`. '}See https://vitest.dev/guide/benchmarking#comparing-benchmarks What it means
`bench.compare()` runs several registrations together and emits a comparison table, so it needs at least two. This `SyntaxError` (see `benchmark.ts:475`) is thrown when fewer than two registrations are passed; the message adapts: with one registration it suggests `.run()`, with zero it tells you to define benchmarks via `bench()`. Registrations are marked consumed before validation so a thrown compare doesn't also trip the unrun-bench warning.
Source
Thrown at packages/vitest/src/runtime/benchmark.ts:475
validateBenchmarkProject(config)
// extract optional trailing BenchRunOptions argument
const lastArg = args.at(-1)
const isOptions = lastArg != null && typeof lastArg === 'object' && !(kRegistration in lastArg)
const benchOptions = isOptions ? args.pop() as BenchRunOptions : undefined
const registrations = args as BenchRegistration<any>[]
// Mark every passed-in registration as consumed before validation so a
// throwing `bench.compare()` (wrong arity, wrong shape) doesn't also
// trigger the unrun-bench warning — the user's intent was to consume them.
for (const reg of registrations) {
if (reg != null && typeof reg === 'object' && kRegistration in reg) {
pending.delete(reg)
}
}
if (registrations.length < 2) {
throw new SyntaxError(`\`bench.compare()\` requires at least 2 benchmarks, received ${registrations.length} instead. ${registrations.length === 1 ? 'Consider calling `bench().run()`. ' : 'Define benchmarks by calling `bench()`. '}See https://vitest.dev/guide/benchmarking#comparing-benchmarks`)
}
for (const reg of registrations) {
if (reg == null || typeof reg !== 'object' || !(kRegistration in reg)) {
throw new SyntaxError('`bench.compare()` expects every argument to be the return value of `bench` or `bench.from`.')
}
}
const runnable: RunnableRegistration<any>[] = []
const fromEntries: FromRegistration<any>[] = []
for (const reg of registrations) {
if (isFromRegistration(reg)) {
fromEntries.push(reg)
}
else {
runnable.push(reg as RunnableRegistration<any>)
}
}
View on GitHub (pinned to d568f8ce37)
Solutions
- If you have exactly one benchmark, call `await reg.run()` instead of `bench.compare(reg)`.
- If comparing, pass at least two registrations: `await bench.compare(regA, regB)`.
- Guard dynamic arrays: only call `compare` when `regs.length >= 2`, otherwise call `.run()` on the single registration.
Example fix
// before
const regs = []
if (cond) regs.push(bench('a', fnA))
await bench.compare(...regs)
// after
if (regs.length >= 2) await bench.compare(...regs)
else if (regs.length === 1) await regs[0].run() Defensive patterns
Strategy: validation
Validate before calling
// Only call compare when you have 2+ registrations
const regs = [maybeA, maybeB].filter(Boolean) as BenchRegistration<string>[]
let storage
if (regs.length >= 2) {
storage = await bench.compare(...regs)
} else if (regs.length === 1) {
storage = { get: () => await regs[0].run() }
} else {
throw new Error('No benchmarks defined to compare or run')
} Try / catch
try {
await bench.compare(...regs)
} catch (e) {
if (e instanceof SyntaxError && /requires at least 2 benchmarks/.test(e.message)) {
// fall back to running the single registration
if (regs.length === 1) await regs[0].run()
} else throw e
} Prevention
- Guard dynamic registration arrays with a length check before calling compare.
- For a single benchmark, prefer reg.run() over bench.compare(reg).
- Log the registration count during development to catch empty arrays early.
When it happens
Trigger: `await bench.compare()` with no args; `await bench.compare(singleReg)`; building a registrations array dynamically that ends up empty or singleton.
Common situations: Conditionally pushing registrations into an array that's sometimes empty; refactoring a single benchmark and forgetting to switch from `compare` to `.run()`; passing a single `bench.from` baseline.
Related errors
- `bench.compare()` expects every argument to be the return va
- task "${name}" was not defined
- benchmark provider did not return a result for "${name}"
- `bench.from()` requires a name (string or named function) as
- `bench.from()` expects a string path or a function returning
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/2bb8a6f3802fb704.json.
Report an issue: GitHub.