jestjs/jest · error · Error
received value must be a function
Error message
received value must be a function
What it means
Thrown by `toThrow` / `toThrowError` (toThrowMatchers.ts:78, via `createMatcher`) when the value passed to `expect(...)` is not a function and the matcher was not invoked through `.rejects` (the `fromPromise` path). `toThrow` works by calling `received()` inside a try/catch to capture the thrown error; a non-function received cannot be invoked. The check is gated by `!fromPromise`, so `expect(promise).rejects.toThrow()` does not hit this — only the synchronous misuse does.
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 f49721c78e)
Solutions
- Pass the function reference, not its result: `expect(fn).toThrow()` (no parens on `fn`).
- For async rejections, use `expect(promise).rejects.toThrow()`.
- Wrap an inline expression in an arrow function: `expect(() => parse(bad)).toThrow()`.
- If you already have the error, assert on it directly with `expect(err.message).toBe(...)` rather than `toThrow`.
Example fix
// before expect(validate(input)).toThrow(); // validate runs before toThrow // after expect(() => validate(input)).toThrow();
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof received !== 'function') {
throw new Error(`received must be a function for toThrow, got ${typeof received}`);
}
expect(received).toThrow(); Type guard
const isFunction = (v: unknown): v is (...args: any[]) => any => typeof v === 'function';
Try / catch
try {
expect(received).toThrow();
} catch (e) {
if (e instanceof Error && /received value must be a function/.test(e.message)) {
console.error('pass the function reference, not its result (drop the parens)');
}
throw e;
} Prevention
- Pass the function reference: `expect(fn).toThrow()`, never `expect(fn()).toThrow()`.
- Wrap inline expressions: `expect(() => parse(bad)).toThrow()`.
- For async rejections, use `expect(promise).rejects.toThrow()`.
When it happens
Trigger: Calling `expect(value).toThrow()` where `value` is a string, number, object, undefined, null, or the result of calling a function (instead of the function reference itself). Common: `expect(fn()).toThrow()` — the parens invoke `fn` before `toThrow` can wrap it, so `received` is the return value, not the function. Also `expect(asyncFn()).toThrow()` on a non-awaited async call (should use `.rejects.toThrow()`).
Common situations: Adding parentheses by accident (`expect(fn())` instead of `expect(fn)`); forgetting `.rejects` for async-rejection assertions; passing an error instance directly instead of a throwing function; refactoring from a try/catch test style.
Related errors
- received value must be a number
- received value must be a non-null object
- expected value must be a string or regular expression or cla
- expected value must be a number
- expected value must be a function
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/82e8e13ea496a564.json.
Report an issue: GitHub.