jestjs/jest · error · Error
received value must be a non-null object
Error message
received value must be a non-null object
What it means
Thrown by `toMatchObject` (matchers.ts:894) when the value passed to `expect(...)` is not a non-null object. `toMatchObject` performs a subset deep-equality check (`equals` with `subsetEquality` tester) that walks properties, so it requires a real object; primitives, null, and undefined cannot be subset-matched. The check uses `typeof received !== 'object' || received === null`, so arrays pass (they are objects) but `null` does not.
Source
Thrown at packages/expect/src/matchers.ts:902
matcherHint(matcherName, undefined, undefined, options) +
'\n\n' +
`${printLabel(labelExpected)}${printExpected(expected)}\n` +
`${printLabel(labelReceived)}${printReceived(received)}`
);
};
return {message, pass};
},
toMatchObject(received: object, expected: object) {
const matcherName = 'toMatchObject';
const options: MatcherHintOptions = {
isNot: this.isNot,
promise: this.promise,
};
if (typeof received !== 'object' || received === null) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, undefined, options),
`${RECEIVED_COLOR('received')} value must be a non-null object`,
printWithType('Received', received, printReceived),
),
);
}
if (typeof expected !== 'object' || expected === null) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, undefined, options),
`${EXPECTED_COLOR('expected')} value must be a non-null object`,
printWithType('Expected', expected, printExpected),
),
);
}
View on GitHub (pinned to f49721c78e)
Solutions
- If async, await it: `expect(await fetchThing()).toMatchObject({id: 1})`.
- Confirm the producer returns an object — log `typeof value` and the value.
- Use `.resolves.toMatchObject({...})` for promise assertions.
- If null is legitimately possible, guard: `expect(value ?? {}).toMatchObject({...})` only makes sense if you also expect an empty object.
Example fix
// before
expect(api.getUser(id)).toMatchObject({id}); // forgot await
// after
expect(await api.getUser(id)).toMatchObject({id}); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof received !== 'object' || received === null) {
throw new Error(`received must be a non-null object, got ${received === null ? 'null' : typeof received}`);
}
expect(received).toMatchObject(subset); Type guard
const isNonNullObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null;
Try / catch
try {
expect(received).toMatchObject(subset);
} catch (e) {
if (e instanceof Error && /received value must be a non-null object/.test(e.message)) {
console.error('received was', typeof received, received);
}
throw e;
} Prevention
- Await async producers or use `.resolves.toMatchObject(...)`.
- Assert `toBeDefined()` before deep matching to localize failures.
- Type producers as returning `object` so TypeScript flags misuse.
When it happens
Trigger: Calling `expect(value).toMatchObject({...})` where `value` is a string, number, boolean, undefined, null, or a function. Common with `expect(fetchThing()).toMatchObject({id: 1})` where `fetchThing` returns undefined or the call wasn't awaited.
Common situations: Async function not awaited; API returning null for a 404; consuming a primitive where an object wrapper was expected; refactor that flattened an object into a string; mock forgetting to return an object.
Related errors
- received value must be a number
- expected value must be a non-null object
- received value must be a function
- 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/6199b394181a34fb.json.
Report an issue: GitHub.