jestjs/jest · error · TypeError
received value must be a number
Error message
received value must be a number
What it means
Thrown by `toBeCloseTo` (matchers.ts:142) when the value passed into `expect(...)` (the `received` argument) is not a number. The matcher needs to subtract `received` from `expected` to measure the difference against `Math.pow(10, -precision) / 2`, so a non-numeric received value makes the comparison meaningless. Jest validates this after the expected-value check and throws a `TypeError` with a `printWithType` hint showing the actual type.
Source
Thrown at packages/expect/src/matchers.ts:164
const options: MatcherHintOptions = {
isNot,
promise: this.promise,
secondArgument,
secondArgumentColor: (arg: string) => arg,
};
if (typeof expected !== 'number') {
throw new TypeError(
matcherErrorMessage(
matcherHint(matcherName, undefined, undefined, options),
`${EXPECTED_COLOR('expected')} value must be a number`,
printWithType('Expected', expected, printExpected),
),
);
}
if (typeof received !== 'number') {
throw new TypeError(
matcherErrorMessage(
matcherHint(matcherName, undefined, undefined, options),
`${RECEIVED_COLOR('received')} value must be a number`,
printWithType('Received', received, printReceived),
),
);
}
let pass = false;
let expectedDiff = 0;
let receivedDiff = 0;
if (
received === Number.POSITIVE_INFINITY &&
expected === Number.POSITIVE_INFINITY
) {
pass = true; // Infinity - Infinity is NaN
} else if (View on GitHub (pinned to f49721c78e)
Solutions
- If the source is async, await it first or use `expect(fetchMetric()).resolves.toBeCloseTo(0.5)`.
- Coerce string inputs: `expect(Number(input.value)).toBeCloseTo(0.5)`.
- Add a `typeof` guard or an `expect(typeof value).toBe('number')` precondition to localize the defect.
- Check the producer of the value (the function under test) — it likely has a bug returning a non-number.
Example fix
// before expect(getRatio()).toBeCloseTo(0.5); // getRatio returns '0.5' // after expect(Number(getRatio())).toBeCloseTo(0.5);
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof received !== 'number' || !Number.isFinite(received)) {
throw new Error(`received must be a finite number, got ${typeof received}: ${received}`);
}
expect(received).toBeCloseTo(expectedVal, precision); Type guard
const isFiniteNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);
Try / catch
try {
expect(received).toBeCloseTo(expectedVal, precision);
} catch (e) {
if (e instanceof TypeError && /received value must be a number/.test(e.message)) {
console.error('received was', typeof received, received);
}
throw e;
} Prevention
- Await async producers before asserting, or use `.resolves.toBeCloseTo(...)`.
- Coerce DOM/JSON string numbers with `Number(...)` before the assertion.
- Type the function under test to return `number` so TypeScript catches misuse.
When it happens
Trigger: Calling `expect(value).toBeCloseTo(1.5)` where `value` is the result of a function that returned a string (`'1.6'`), `undefined`, `null`, an object, or a Promise that was not awaited. Common with `expect(fetchMetric()).toBeCloseTo(0.5)` where `fetchMetric` is async and missing `await`/`.resolves`.
Common situations: Forgetting to await an async function before asserting on its return value; consuming a DOM input's `.value` (always a string) without coercion; a stubbed/mock return value that defaulted to `undefined`; migrating from Jasmine where a custom equality tester previously coerced types.
Related errors
- expected value must be a number
- received value must be a non-null object
- received value must be a function
- expected value must be a function
- expected value must be a string if received value is a strin
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/8ca0af8b86685d1b.json.
Report an issue: GitHub.