jestjs/jest · error · Error
${RECEIVED_COLOR('received')} value must be a function
Error message
${RECEIVED_COLOR('received')} value must be a function What it means
Thrown by the `toThrow` matcher factory (toThrowMatchers.ts:102) when, in the synchronous (non-promise) path, the received value is not a function. `toThrow` invokes `received()` inside a try/catch to capture a thrown error, so it requires a callable. The guard is skipped only when `fromPromise` is true (i.e. `.rejects.toThrow()`), where received is already the rejection reason.
Source
Thrown at packages/expect/src/toThrowMatchers.ts:102
isNot: this.isNot,
promise: this.promise,
};
let thrown = null;
if (fromPromise && isError(received)) {
thrown = getThrown(received);
} else {
if (typeof received === 'function') {
try {
received();
} catch (error) {
thrown = getThrown(error);
}
} else {
if (!fromPromise) {
const placeholder = expected === undefined ? '' : 'expected';
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, placeholder, options),
`${RECEIVED_COLOR('received')} value must be a function`,
printWithType('Received', received, printReceived),
),
);
}
}
}
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);View on GitHub (pinned to 8e6d128e4a)
Solutions
- Pass the function reference, not its result: expect(fn).toThrow(), not expect(fn()).toThrow().
- For async rejections, use await expect(promise).rejects.toThrow() so the promise path is taken.
- If the value is genuinely not a function, use a different matcher (toBeInstanceOf, toEqual) for it.
- Wrap an inline throw in an arrow function: expect(() => { throw new Error() }).toThrow().
Example fix
// before expect(throwIfBad(input)).toThrow(); // invokes eagerly, no fn expect(badValue).toThrow(); // badValue is not callable // after expect(() => throwIfBad(input)).toThrow(); expect(throwIfBad).toThrow(); // async await expect(promise).rejects.toThrow();
Defensive patterns
Strategy: type-guard
Validate before calling
const v = received;
if (typeof v !== 'function') {
throw new Error('toThrow requires a function reference, not its result');
}
expect(v).toThrow();
// for async: await expect(promise).rejects.toThrow(); Type guard
const isFunction = (v: unknown): v is Function => typeof v === 'function';
Try / catch
// wrap inline behaviour in an arrow fn
expect(() => {
throwIfBad(input);
}).toThrow(); Prevention
- Pass the function reference, not fn().
- Use .rejects.toThrow() for promise rejections.
- Wrap inline throws in () => { ... } for toThrow.
When it happens
Trigger: Calling `expect(value).toThrow()` where `value` is a number, string, object, null, undefined, or the result of calling a function (instead of the function itself). The most common mistake is invoking the function (`expect(fn()).toThrow()`) so received is the return value, not the function.
Common situations: Passing `fn()` instead of `fn` (eager invocation) — the error throws before expect can catch it, or a non-error return reaches the matcher; passing a value you expected to be a function; forgetting to use `.rejects` for async rejections (then a Promise is received synchronously).
Related errors
- ${EXPECTED_COLOR('expected')} value must be a string or regu
- ${EXPECTED_COLOR('expected')} value must be a number
- ${RECEIVED_COLOR('received')} value must be a number
- ${EXPECTED_COLOR('expected')} value must be a function
- ${RECEIVED_COLOR('received')} value must not be null nor und
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/d53ec3b479218886.
Report an issue: GitHub.