jestjs/jest · error · TypeError

${EXPECTED_COLOR('expected')} value must be a number

Error message

${EXPECTED_COLOR('expected')} value must be a number

What it means

Thrown by the `toBeCloseTo` matcher (matchers.ts:153) when the `expected` argument (the 2nd parameter, the value to compare against) is not a number. `toBeCloseTo` performs floating-point comparison within a configurable precision, so it must compute `Math.abs(expected - received)`, which requires both operands to be numeric. This guard fires before the received-value check at line 163.

Source

Thrown at packages/expect/src/matchers.ts:154

    // Passing the actual and expected objects so that a custom reporter
    // could access them, for example in order to display a custom visual diff,
    // or create a different error message
    return {actual: received, expected, message, name: matcherName, pass};
  },

  toBeCloseTo(received: number, expected: number, precision = 2) {
    const matcherName = 'toBeCloseTo';
    const secondArgument = arguments.length === 3 ? 'precision' : undefined;
    const isNot = this.isNot;
    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),
        ),
      );
    }

View on GitHub (pinned to 8e6d128e4a)

Solutions

  1. Ensure the second argument to toBeCloseTo is a JS number, not a string: pass 0.3 not '0.3'.
  2. If the value comes from a string source, coerce it before the assertion: Number(value) or parseFloat(value).
  3. Check that the variable holding `expected` is not undefined due to a missing return or wrong property access.
  4. Confirm you did not swap arguments: signature is toBeCloseTo(expected, precision), not toBeCloseTo(precision, expected).

Example fix

// before
expect(0.1 + 0.2).toBeCloseTo('0.3');

// after
expect(0.1 + 0.2).toBeCloseTo(0.3);
// or coerce a string source
expect(0.1 + 0.2).toBeCloseTo(Number(configValue));
Defensive patterns

Strategy: type-guard

Validate before calling

const expected = config.value;
if (typeof expected !== 'number' || !Number.isFinite(expected)) {
  throw new Error(`toBeCloseTo expected must be a finite number, got ${expected}`);
}
expect(received).toBeCloseTo(expected, 2);

Type guard

const isFiniteNumber = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v);

Prevention

When it happens

Trigger: Calling `expect(x).toBeCloseTo(expected, precision)` where `expected` is a string (e.g. '0.3'), null, undefined, an object, or NaN. Also triggered by swapping arguments so a precision number lands in the expected slot, or when expected is sourced from JSON/config as a string and never coerced.

Common situations: Expected value loaded from a JSON fixture or env var (always a string); expected computed by a function that returns undefined on an edge case; migrating from a different assertion library where the argument order for approximate comparison differs.

Related errors


AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10). Data as JSON: /api/errors/4dc6fc9984782018. Report an issue: GitHub.