{"id":"b06c51a654d8bbbf","repo":"jestjs/jest","slug":"matcherhint-received-value-must-be-a-funct","errorCode":null,"errorMessage":"${matcherHint(...)} received value must be a function\n${printWithType('Received', received, printReceived)}","messagePattern":"(.+?) received value must be a function\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-snapshot/src/index.ts","lineNumber":492,"sourceCode":"  );\n};\n\nconst _toThrowErrorMatchingSnapshot = (\n  config: MatchSnapshotConfig,\n  fromPromise?: boolean,\n) => {\n  const {context, hint, inlineSnapshot, isInline, matcherName, received} =\n    config;\n\n  context.dontThrow?.();\n\n  const {isNot, promise} = context;\n\n  if (!fromPromise) {\n    if (typeof received !== 'function') {\n      const options: MatcherHintOptions = {isNot, promise};\n\n      throw new Error(\n        matcherErrorMessage(\n          matcherHint(matcherName, undefined, '', options),\n          `${RECEIVED_COLOR('received')} value must be a function`,\n          printWithType('Received', received, printReceived),\n        ),\n      );\n    }\n  }\n\n  if (isNot) {\n    throw new Error(\n      matcherErrorMessage(\n        matcherHintFromConfig(config, false),\n        NOT_SNAPSHOT_MATCHERS,\n      ),\n    );\n  }\n","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-snapshot/src/index.ts#L474-L510","documentation":"Thrown by `_toThrowErrorMatchingSnapshot` (index.ts:488-499) when `received` is not a function and the call didn't come through the promise path. These matchers wrap a callable to catch its thrown error; passing a non-function (and not resolving via `fromPromise`) means there's nothing to invoke, so Jest surfaces a typed matcher error.","triggerScenarios":"`expect('boom').toThrowErrorMatchingSnapshot()`, `expect(42).toThrowErrorMatchingInlineSnapshot()`, `expect(null).toThrowErrorMatchingSnapshot()`.","commonSituations":"Forgetting to wrap the throwing code in a function: `expect(risky()).toThrowErrorMatchingSnapshot()` evaluates `risky()` first and passes its result. Asserting against an already-caught error object instead of a callable.","solutions":["Pass a function: `expect(() => risky()).toThrowErrorMatchingSnapshot()`.","If asserting on a promise rejection, use the async form or ensure the matcher receives `fromPromise: true` via the runner.","For an already-caught error, use `toMatchSnapshot` on the error object instead."],"exampleFix":"// before\nexpect(parse('bad')).toThrowErrorMatchingSnapshot(); // parse runs first\n\n// after\nexpect(() => parse('bad')).toThrowErrorMatchingSnapshot();","handlingStrategy":"type-guard","validationCode":"if (typeof received !== 'function') {\n  throw new Error('Pass a function: expect(() => fn()).toThrowErrorMatchingSnapshot()');\n}\nexpect(received).toThrowErrorMatchingSnapshot();","typeGuard":"function isFunction(v: unknown): v is Function {\n  return typeof v === 'function';\n}","tryCatchPattern":null,"preventionTips":["Always wrap throwing expressions in an arrow function so they're invoked by the matcher.","For promise rejections, use the async matcher path so `fromPromise` is set.","Lint against `expect(*).toThrow*` where `*` is not a function literal or arrow."],"tags":["snapshot","matcher","argument-validation","tothrow"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}