jestjs/jest · error · Error

expected value must be a number or bigint

Error message

expected value must be a number or bigint

What it means

Thrown by ensureExpectedIsNumber when the EXPECTED value (second argument to the matcher) is not a 'number' or 'bigint'. It is the expected-side twin of error 140: numeric matchers validate both operands. Because the expected argument is often hand-written by the test author (a literal or a config constant), this error usually points at the test code rather than production code.

Source

Thrown at packages/jest-matcher-utils/src/index.ts:207

        `${RECEIVED_COLOR('received')} value must be a number or bigint`,
        printWithType('Received', actual, printReceived),
      ),
    );
  }
};

/**
 * Ensures that `expected` is of type `number | bigint`
 */
export const ensureExpectedIsNumber = (
  expected: unknown,
  matcherName: string,
  options?: MatcherHintOptions,
): void => {
  if (typeof expected !== 'number' && typeof expected !== 'bigint') {
    // Prepend maybe not only for backward compatibility.
    const matcherString = (options ? '' : '[.not]') + matcherName;
    throw new Error(
      matcherErrorMessage(
        matcherHint(matcherString, undefined, undefined, options),
        `${EXPECTED_COLOR('expected')} value must be a number or bigint`,
        printWithType('Expected', expected, printExpected),
      ),
    );
  }
};

/**
 * Ensures that `actual` & `expected` are of type `number | bigint`
 */
export const ensureNumbers = (
  actual: unknown,
  expected: unknown,
  matcherName: string,
  options?: MatcherHintOptions,
): void => {

View on GitHub (pinned to f49721c78e)

Solutions

  1. Inspect the expected operand: log the exact value/typeof you pass on the right side of the matcher and fix its source.
  2. Coerce explicitly when the source is a string/env var: expect(count).toBeLessThan(Number(config.MAX)).
  3. If the expected value is legitimately optional, default it to a number: expect(count).toBeLessThan(config.MAX ?? Infinity).
  4. Confirm both sides share the same numeric domain (number vs bigint) — mixing is allowed only if both are numeric.

Example fix

// before
expect(items.length).toBeLessThan(config.maxItems); // config.maxItems is undefined
// after
expect(items.length).toBeLessThan(Number(config.maxItems));
Defensive patterns

Strategy: validation

Validate before calling

const expected = config.limit;
if (typeof expected !== 'number' && typeof expected !== 'bigint') {
  throw new Error(`expected limit must be numeric, got ${typeof expected}`);
}
expect(count).toBeLessThan(expected);

Type guard

const isNumeric = (v: unknown): v is number | bigint =>
  typeof v === 'number' || typeof v === 'bigint';

const limit = isNumeric(config.limit) ? config.limit : Number(config.limit);
expect(count).toBeLessThan(limit);

Prevention

When it happens

Trigger: Writing a numeric matcher with a string/undefined expected operand: expect(x).toBeGreaterThan('10'); expect(count).toBeLessThan(config.limit) where config.limit is undefined; expect(n).toBeCloseTo('0.1'); expect(bigintVal).toBeGreaterThan(5) is fine, but expect(5).toBeGreaterThan(bigint) where one side is non-numeric triggers it.

Common situations: Typo in a config key returning undefined (config.maxRetries vs config.maxretry); reading from a JSON file as a string and forgetting to convert; destructuring the wrong field; copy-pasting a test and forgetting to update the expected literal from a string.

Related errors


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