vitest-dev/vitest · error · TypeError
${matcherHint('.toBeSlowerThan')} expects the expected value
Error message
${matcherHint('.toBeSlowerThan')} expects the expected value to be a benchmark result. What it means
Thrown by the `.toBeSlowerThan` benchmark matcher when the EXPECTED (second) argument is not a valid `BenchResult`. A valid result is a non-null object with a numeric `latency.mean` (produced by `bench()`/`vitest bench`). The matcher cannot compute a threshold without comparable latency data, so it refuses to proceed rather than returning a misleading pass/fail.
Source
Thrown at packages/vitest/src/integrations/chai/bench.ts:61
+ `Expected: ${EXPECTED_COLOR(formatOps(expected.throughput.mean))} ops/sec\n`
: `${matcherHint('.toBeFasterThan')}\n\nExpected to be faster${delta > 0 ? ` by at least ${(delta * 100).toFixed(0)}%` : ''}, but was ${Number(relation) > 0 ? `${relation}% slower` : `only ${Math.abs(Number(relation))}% faster`}.\n\n`
+ `Received: ${RECEIVED_COLOR(formatOps(actual.throughput.mean))} ops/sec\n`
+ `Expected: ${EXPECTED_COLOR(formatOps(expected.throughput.mean))} ops/sec\n`
},
}
},
toBeSlowerThan(actual: unknown, expected: unknown, options?: { delta?: number }) {
const { matcherHint, RECEIVED_COLOR, EXPECTED_COLOR } = this.utils
const delta = options?.delta ?? 0
if (!isBenchResult(actual)) {
throw new TypeError(
`${matcherHint('.toBeSlowerThan')} expects the actual value to be a benchmark result.`,
)
}
if (!isBenchResult(expected)) {
throw new TypeError(
`${matcherHint('.toBeSlowerThan')} expects the expected value to be a benchmark result.`,
)
}
const threshold = expected.latency.mean * (1 + delta)
const pass = actual.latency.mean > threshold
return {
pass,
message: () => {
const relation = ((actual.latency.mean - expected.latency.mean) / expected.latency.mean * 100).toFixed(2)
return pass
? `${matcherHint('.not.toBeSlowerThan')}\n\nExpected to not be slower, but was ${relation}% slower.\n\n`
+ `Received: ${RECEIVED_COLOR(formatOps(actual.throughput.mean))} ops/sec\n`
+ `Expected: ${EXPECTED_COLOR(formatOps(expected.throughput.mean))} ops/sec\n`
: `${matcherHint('.toBeSlowerThan')}\n\nExpected to be slower${delta > 0 ? ` by at least ${(delta * 100).toFixed(0)}%` : ''}, but was ${Number(relation) < 0 ? `${Math.abs(Number(relation))}% faster` : `only ${relation}% slower`}.\n\n`
+ `Received: ${RECEIVED_COLOR(formatOps(actual.throughput.mean))} ops/sec\n`
+ `Expected: ${EXPECTED_COLOR(formatOps(expected.throughput.mean))} ops/sec\n`View on GitHub (pinned to d568f8ce37)
Solutions
- Pass a full `BenchResult` object as the expected value, produced by another `bench()`/`vitest bench` task.
- If you want a numeric latency comparison, write a custom assertion or use `expect(actual.latency.mean).toBeGreaterThan(expectedMs)` instead.
- Verify the expected value has `typeof expected.latency.mean === 'number'` before calling the matcher.
Example fix
// before
expect(result).toBeSlowerThan(100)
// after
const baseline = await bench('baseline', baselineFn)
expect(result).toBeSlowerThan(baseline, { delta: 0.1 }) Defensive patterns
Strategy: type-guard
Validate before calling
function isBenchResult(v: unknown): v is { latency: { mean: number }; throughput: { mean: number } } {
return typeof v === 'object' && v !== null
&& typeof (v as any).latency?.mean === 'number'
} Type guard
import { bench } from 'vitest'
// vitest does not export isBenchResult publicly; use the local shape check above
const ok = isBenchResult(expected)
if (!ok) throw new Error('expected is not a bench result')
expect(actual).toBeSlowerThan(expected) Prevention
- Always pass objects returned by `bench()` tasks as both arguments to `.toBeFasterThan`/`.toBeSlowerThan`.
- Avoid passing raw millisecond numbers; convert numeric comparisons to `.toBeGreaterThan` on `latency.mean`.
When it happens
Trigger: Calling `expect(actualResult).toBeSlowerThan(expected)` where `expected` is a plain number, string, raw function, undefined, or any object lacking a numeric `latency.mean`. Both arguments must originate from `bench()` tasks.
Common situations: Passing a millisecond number instead of a bench result object (e.g. `.toBeSlowerThan(100)`), comparing against a pre-saved number, or destructuring a result incorrectly so `latency` is undefined. Also happens when comparing a `bench()` result against a result from a different benchmarking library.
Related errors
- .toContainHTML() expects a string value, got ${htmlText}
- You must provide an array or set to ${matcherHint('.toBeOneO
- ${utils.inspect(chain)} is not a `vi.when` instance
- expected must be a function, received ${typeof expected}
- snapshot function didn't throw
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/22e78e909b445919.json.
Report an issue: GitHub.