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

  1. If the source is async, await it first or use `expect(fetchMetric()).resolves.toBeCloseTo(0.5)`.
  2. Coerce string inputs: `expect(Number(input.value)).toBeCloseTo(0.5)`.
  3. Add a `typeof` guard or an `expect(typeof value).toBe('number')` precondition to localize the defect.
  4. 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

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


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/8ca0af8b86685d1b.json. Report an issue: GitHub.