jestjs/jest · error · TypeError

expected value must be a function

Error message

expected value must be a function

What it means

Thrown by `toBeInstanceOf` (matchers.ts:295) when the `expected` argument is not a function (i.e. not a constructor/class). `received instanceof expected` requires the right-hand side to be a callable constructor; anything else is a programmer error, not a test outcome. Jest throws a `TypeError` with `printWithType('Expected', expected, ...)` to surface what was passed.

Source

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

    const message = () =>
      // eslint-disable-next-line prefer-template
      matcherHint(matcherName, undefined, undefined, options) +
      '\n\n' +
      `Expected:${isNot ? ' not' : ''} >= ${printExpected(expected)}\n` +
      `Received:${isNot ? '    ' : ''}    ${printReceived(received)}`;

    return {message, pass};
  },

  toBeInstanceOf(received: any, expected: Function) {
    const matcherName = 'toBeInstanceOf';
    const options: MatcherHintOptions = {
      isNot: this.isNot,
      promise: this.promise,
    };

    if (typeof expected !== 'function') {
      throw new TypeError(
        matcherErrorMessage(
          matcherHint(matcherName, undefined, undefined, options),
          `${EXPECTED_COLOR('expected')} value must be a function`,
          printWithType('Expected', expected, printExpected),
        ),
      );
    }

    const pass = received instanceof expected;

    const message = pass
      ? () =>
          // eslint-disable-next-line prefer-template
          matcherHint(matcherName, undefined, undefined, options) +
          '\n\n' +
          printExpectedConstructorNameNot('Expected constructor', expected) +
          (typeof received.constructor === 'function' &&
          received.constructor !== expected

View on GitHub (pinned to f49721c78e)

Solutions

  1. Pass the constructor/class itself, not an instance or its name: `.toBeInstanceOf(Error)`.
  2. Verify the import resolves to a real class — log `typeof Expected` (should be `'function'`).
  3. If the class is dynamically mocked, ensure the mock returns the constructor, not an instance.
  4. If you only have a class name string, use `.toThrow()` with a string or match the constructor name manually.

Example fix

// before
import { MyError } from './errors'; // MyError is actually an instance or undefined
expect(err).toBeInstanceOf(MyError);

// after
import { MyErrorClass } from './errors';
expect(err).toBeInstanceOf(MyErrorClass);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof ExpectedClass !== 'function') {
  throw new Error(`Expected must be a class/function, got ${typeof ExpectedClass}`);
}
expect(value).toBeInstanceOf(ExpectedClass);

Type guard

const isConstructor = (v: unknown): v is new (...args: any[]) => any =>
  typeof v === 'function';

Try / catch

try {
  expect(value).toBeInstanceOf(ExpectedClass);
} catch (e) {
  if (e instanceof TypeError && /must be a function/.test(e.message)) {
    console.error('ExpectedClass was', ExpectedClass);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `expect(x).toBeInstanceOf('Error')` (string instead of class), `expect(x).toBeInstanceOf({name: 'Error'})` (object literal), `expect(x).toBeInstanceOf(errorInstance)` (an instance instead of the class), or `expect(x).toBeInstanceOf(undefined)` when the imported class failed to load (e.g. named export mismatch).

Common situations: Importing a class under the wrong name (`import {Errors} from './errors'` when the export is `Error`); passing an instance rather than a constructor; mocking a class export so the import becomes `undefined`; copy-pasting a string error name from documentation.

Related errors


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