jestjs/jest · error · Error

${EXPECTED_COLOR('expected')} value must be a string or regu

Error message

${EXPECTED_COLOR('expected')} value must be a string or regular expression or class or error

What it means

Thrown by the `toThrow` matcher factory (toThrowMatchers.ts:129) when the `expected` argument matches none of the supported forms: string (substring), function/class (constructor), RegExp-like (.test), asymmetric matcher (.asymmetricMatch), or error object. If expected is something else (number, boolean, null, plain non-Error object without the right shape), the matcher cannot decide how to match the thrown value and aborts.

Source

Thrown at packages/expect/src/toThrowMatchers.ts:129

    }

    if (expected === undefined) {
      return toThrow(matcherName, options, thrown);
    } else if (typeof expected === 'function') {
      return toThrowExpectedClass(matcherName, options, thrown, expected);
    } else if (typeof expected === 'string') {
      return toThrowExpectedString(matcherName, options, thrown, expected);
    } else if (expected !== null && typeof expected.test === 'function') {
      return toThrowExpectedRegExp(matcherName, options, thrown, expected);
    } else if (
      expected !== null &&
      typeof expected.asymmetricMatch === 'function'
    ) {
      return toThrowExpectedAsymmetric(matcherName, options, thrown, expected);
    } else if (expected !== null && typeof expected === 'object') {
      return toThrowExpectedObject(matcherName, options, thrown, expected);
    } else {
      throw new Error(
        matcherErrorMessage(
          matcherHint(matcherName, undefined, undefined, options),
          `${EXPECTED_COLOR(
            'expected',
          )} value must be a string or regular expression or class or error`,
          printWithType('Expected', expected, printExpected),
        ),
      );
    }
  };

const matchers: MatchersObject = {
  toThrow: createMatcher('toThrow'),
};

const toThrowExpectedRegExp = (
  matcherName: string,
  options: MatcherHintOptions,

View on GitHub (pinned to 8e6d128e4a)

Solutions

  1. Pass a substring message, a RegExp, an Error class, or an Error instance: toThrow('not found'), toThrow(NotFound), toThrow(/not found/), toThrow(new Error('x')).
  2. For numeric/string codes on custom errors, assert on the thrown instance via a class: toThrow(MyError) and then check .code separately.
  3. Use an asymmetric matcher for flexible matching: toThrow({message: expect.stringContaining('x')}) (note: object path expects an Error-like shape).
  4. If expected may be null/undefined from a lookup, default it or branch the test.

Example fix

// before
expect(fn).toThrow(404);
expect(fn).toThrow({code: 'ERR'});

// after
expect(fn).toThrow('not found');
expect(fn).toThrow(NotFoundError);
expect(fn).toThrow(/not found/);
expect(fn).toThrow(new NotFoundError());
Defensive patterns

Strategy: type-guard

Validate before calling

const expected = matcher;
const ok =
  expected === undefined ||
  typeof expected === 'string' ||
  typeof expected === 'function' ||
  (expected instanceof RegExp) ||
  (expected != null && typeof (expected as any).test === 'function') ||
  (expected != null && typeof (expected as any).asymmetricMatch === 'function') ||
  (expected != null && typeof expected === 'object');
if (!ok) {
  throw new Error('toThrow expected must be string | RegExp | class | Error | asymmetric matcher');
}
expect(fn).toThrow(expected);

Type guard

type ToThrowExpected =
  | string
  | RegExp
  | (new (...args: any[]) => Error)
  | Error
  | { asymmetricMatch: (v: unknown) => boolean };
const isToThrowExpected = (v: unknown): v is ToThrowExpected =>
  v == null ? false :
  typeof v === 'string' || typeof v === 'function' ||
  typeof (v as any).test === 'function' ||
  typeof (v as any).asymmetricMatch === 'function' ||
  (typeof v === 'object' && v instanceof Error);

Prevention

When it happens

Trigger: Calling `expect(fn).toThrow(404)` (number), `toThrow(true)` (boolean), `toThrow(null)`, `toThrow({code: 1})` with a plain object that is not an Error, or `toThrow(['msg'])` (array).

Common situations: Passing an error code/number instead of a class or message; passing a plain object to match a thrown non-Error; intending an asymmetric matcher but passing a raw value; a variable resolving to null.

Related errors


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