vitest-dev/vitest · error · TypeError
${matcherHint('.toBeFasterThan')} expects the actual value t
Error message
${matcherHint('.toBeFasterThan')} expects the actual value to be a benchmark result. What it means
Thrown by the toBeFasterThan benchmark matcher in packages/vitest/src/integrations/chai/bench.ts when the actual value (the receiver of expect()) is not a BenchResult — i.e. an object with a numeric latency.mean produced by vitest's bench() API. The matcher compares benchmark statistics, so passing a plain number or non-bench object makes the comparison meaningless; Vitest throws a TypeError rather than silently degrading.
Source
Thrown at packages/vitest/src/integrations/chai/bench.ts:23
return (
typeof value === 'object'
&& value !== null
&& 'latency' in value
&& typeof (value as any).latency?.mean === 'number'
)
}
function formatOps(ops: number): string {
return ops.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}
export const benchMatchers: MatchersObject = {
toBeFasterThan(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('.toBeFasterThan')} expects the actual value to be a benchmark result.`,
)
}
if (!isBenchResult(expected)) {
throw new TypeError(
`${matcherHint('.toBeFasterThan')} 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.toBeFasterThan')}\n\nExpected to not be faster, but was ${Math.abs(Number(relation))}% faster.\n\n`View on GitHub (pinned to d568f8ce37)
Solutions
- Use toBeFasterThan only inside a bench() task, passing the benchmark result object that vitest provides.
- For plain numeric comparisons use toBeLessThan, not toBeFasterThan.
- Capture the BenchResult from bench() and pass it to expect(): const result = await bench(...); expect(result).toBeFasterThan(baseline).
- Confirm you imported the bench matchers (they ship with vitest) and are inside a benchmark run.
Example fix
// before
expect(50).toBeFasterThan(baseline)
// after
import { bench, expect } from 'vitest'
bench('op', () => { /* ... */ })
// inside a benchmark task, expect() receives the BenchResult
expect(actualBenchResult).toBeFasterThan(baselineBenchResult) Defensive patterns
Strategy: type-guard
Validate before calling
function isBenchResult(value: unknown): value is { latency: { mean: number }; throughput: { mean: number } } {
return typeof value === 'object' && value !== null
&& 'latency' in value && typeof (value as any).latency?.mean === 'number'
} Type guard
function isBenchResult(value: unknown): value is { latency: { mean: number }; throughput: { mean: number } } {
return typeof value === 'object' && value !== null
&& 'latency' in value && typeof (value as any).latency?.mean === 'number'
} Prevention
- Only call toBeFasterThan inside bench() tasks where expect() receives a BenchResult.
- Use toBeLessThan for plain numeric comparisons.
- Capture and reuse baseline BenchResult objects across runs.
When it happens
Trigger: expect(myNumber).toBeFasterThan(other); using toBeFasterThan outside of a bench() task where expect() receives the result of a normal assertion; passing a raw timing value instead of the BenchResult returned by bench.
Common situations: Confusing benchmark matchers with regular numeric matchers; refactoring a bench task so expect() no longer receives the BenchResult; calling toBeFasterThan inside an it() instead of a bench() block.
Related errors
- ${matcherHint('.toBeFasterThan')} expects the expected value
- ${matcherHint('.toBeSlowerThan')} expects the actual value t
- .toContainHTML() expects a string value, got ${htmlText}
- Exact option does not support RegExp expected class names
- .toHaveDisplayValue() currently supports only input, textare
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/e3ddaf36b73f573d.json.
Report an issue: GitHub.