vitest-dev/vitest · error · SyntaxError
`bench.compare()` expects every argument to be the return…
Error message
`bench.compare()` expects every argument to be the return value of `bench` or `bench.from`.
What it means
Every argument to `bench.compare(...)` (except an optional trailing options object) must be the return value of `bench()` or `bench.from()` — objects carrying the internal `kRegistration` symbol. This `SyntaxError` fires when any argument is null, a primitive, or a plain object that is not a registration.
Solutions
- Pass only values returned by `bench(...)` or `bench.from(...)`.
- Filter out falsy values before spreading: `bench.compare(...regs.filter(Boolean))`.
- If you intended to compare against a baseline, wrap it: `bench.from('name', () => baseline)` then pass the result.
Example fix
// before
bench.compare(regA, baselineData)
// after
const regB = bench.from('baseline', () => baselineData)
bench.compare(regA, regB) Defensive patterns
Strategy: type-guard
Validate before calling
if (!args.every(a => a != null && typeof a === 'object' && kRegistration in a)) throw new Error('all args must be bench()/bench.from() results') Type guard
function isRegistration(v: unknown): v is BenchRegistration<any> { return v != null && typeof v === 'object' && typeof (v as any)?.[kRegistration] === 'boolean' } Try / catch
null
Prevention
- Only pass values directly returned by `bench()` or `bench.from()`.
- Filter spreads with `.filter(Boolean)` to drop holes.
- Wrap baseline data in `bench.from` before comparing.
When it happens
Trigger: Calling `bench.compare(reg, 'not-a-reg')`, `bench.compare(reg, null)`, `bench.compare(reg, { name: 'x' })` (plain object without the symbol), or `bench.compare(reg, undefined)`. The loop at benchmark.ts:477-481 checks each arg for `kRegistration in reg`.
Common situations: Passing a benchmark function instead of its registration; passing the result of `.run()` (a promise/result) instead of the registration; conditional spreads that include `undefined`; passing a baseline data object instead of a `bench.from()` registration.
Related errors
- `bench.compare()` requires at least 2 benchmarks, received
- task " " was not defined
- `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)…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/250a7657136d639c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/benchmark.ts:479
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>)
}
}
const taskMeta = new Map<string, TaskMeta>()
for (const reg of runnable) {
if (reg[kPerProject]) {
taskMeta.set(reg.name, { perProject: true })View on GitHub (pinned to 1fa9837ec2)