{"record":{"id":"973c527dc63d3130","repo":"jestjs/jest","slug":"received-color-received-value-must-be-a-mock-973c52","errorCode":null,"errorMessage":"${RECEIVED_COLOR('received')} value must be a mock function","messagePattern":"(.+?) value must be a mock function","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/expect/src/spyMatchers.ts","lineNumber":1289,"sourceCode":"  if (!isMock(received) && !isSpy(received)) {\n    throw new Error(\n      matcherErrorMessage(\n        matcherHint(matcherName, undefined, expectedArgument, options),\n        `${RECEIVED_COLOR('received')} value must be a mock or spy function`,\n        printWithType('Received', received, printReceived),\n      ),\n    );\n  }\n};\n\nconst ensureMock = (\n  received: any,\n  matcherName: string,\n  expectedArgument: string,\n  options: MatcherHintOptions,\n) => {\n  if (!isMock(received)) {\n    throw new Error(\n      matcherErrorMessage(\n        matcherHint(matcherName, undefined, expectedArgument, options),\n        `${RECEIVED_COLOR('received')} value must be a mock function`,\n        printWithType('Received', received, printReceived),\n      ),\n    );\n  }\n};\n\nexport default spyMatchers;\n","sourceCodeStart":1271,"sourceCodeEnd":1300,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/expect/src/spyMatchers.ts#L1271-L1300","documentation":"Thrown by `ensureMock` (spyMatchers.ts:1288), used by toHaveReturned, toHaveReturnedTimes, toHaveReturnedWith, toHaveLastReturnedWith, and toHaveNthReturnedWith. It fires when the received value is a Jest mock (`_isMockFunction === true`) is false. These return-value matchers need `received.mock.results`, which only Jest mocks expose — a Jasmine spy (which has `.calls` but no `.mock.results`) is also rejected, hence a stricter guard than ensureMockOrSpy.","triggerScenarios":"Calling `expect(fn).toHaveReturnedWith(value)` where fn is a plain function, a Jasmine spy (has .calls but not .mock), undefined, or any non-Jest-mock value.","commonSituations":"Using a Jasmine-style spy (e.g. from an older/jasmine-jquery setup) and expecting Jest return semantics; forgot jest.fn(); passing the original function instead of the mock; the mock was lost after a re-import.","solutions":["Use jest.fn() so the function has a .mock.results array: const fn = jest.fn().","If you only have a spy and need call-count semantics, use toHaveBeenCalledWith (which accepts spies) instead of the toHaveReturned family.","Confirm the reference passed to expect() is the jest.fn() itself, not a wrapper or the original.","Ensure module isolation so the mock attaches where the code actually calls it."],"exampleFix":"// before\nconst fn = jasmine.createSpy('fn'); // or a plain fn\nfn();\nexpect(fn).toHaveReturnedWith(undefined); // not a jest mock\n\n// after\nconst fn = jest.fn();\nfn();\nexpect(fn).toHaveReturnedWith(undefined);\n// if you must use a spy, use call-based matchers\nexpect(fn).toHaveBeenCalled();","handlingStrategy":"type-guard","validationCode":"const fn = received;\nif (!(fn != null && fn._isMockFunction === true)) {\n  throw new Error('return matchers require a jest.fn() (not a plain fn or jasmine spy)');\n}\nexpect(fn).toHaveReturnedWith(value);","typeGuard":"const isJestMock = (v: unknown): boolean =>\n  v != null && (v as any)._isMockFunction === true;","tryCatchPattern":null,"preventionTips":["Use jest.fn() for any assertion in the toHaveReturned family.","If you only have a spy, use toHaveBeenCalledWith instead.","Keep the mock reference, not the original function, when asserting."],"tags":["jest","expect","matcher","spy","mock","type-error","tohavereturned"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}