{"record":{"id":"a057dae8a9bee8b9","repo":"jestjs/jest","slug":"cannot-replace-the-string-propertykey-proper-a057da","errorCode":null,"errorMessage":"Cannot replace the `${String(propertyKey)}` property because it is a function. Use `jest.spyOn(object, '${String(propertyKey)}')` instead.","messagePattern":"Cannot replace the `(.+?)` property because it is a function\\. Use `jest\\.spyOn\\(object, '(.+?)'\\)` instead\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/jest-mock/src/index.ts","lineNumber":1510,"sourceCode":"          propertyKey,\n        )}\\` property because it has a getter. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}', 'get').mockReturnValue(value)\\` instead.`,\n      );\n    }\n\n    if (descriptor.set !== undefined) {\n      throw new Error(\n        `Cannot replace the \\`${String(\n          propertyKey,\n        )}\\` property because it has a setter. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}', 'set').mockReturnValue(value)\\` instead.`,\n      );\n    }\n\n    if (typeof descriptor.value === 'function') {\n      throw new TypeError(\n        `Cannot replace the \\`${String(\n          propertyKey,\n        )}\\` property because it is a function. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}')\\` instead.`,\n      );\n    }\n\n    const existingRestore = this._findReplacedProperty(object, propertyKey);\n\n    if (existingRestore) {\n      return existingRestore.replaced.replaceValue(value);\n    }\n\n    const isPropertyOwner = Object.prototype.hasOwnProperty.call(\n      object,\n      propertyKey,\n    );","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-mock/src/index.ts#L1492-L1528","documentation":"Thrown by jest.replaceProperty (as a TypeError) when descriptor.value is a function. replaceProperty is meant for value properties; functions must be spied on with spyOn so call tracking and mockImplementation work. The message directs you to the correct API.","triggerScenarios":"jest.replaceProperty(obj,'method',newFn) where obj.method is a function.","commonSituations":"Confusing replaceProperty with spyOn; an API where a value became a method; auto-binded method properties.","solutions":["Use jest.spyOn(obj,'method').mockImplementation(newFn) for function properties.","Reserve jest.replaceProperty for non-function values (numbers, strings, objects).","Confirm with typeof obj.method === 'function' before choosing the API."],"exampleFix":"// before\njest.replaceProperty(svc, 'fetch', mockFn); // fetch is a function\n// after\njest.spyOn(svc, 'fetch').mockImplementation(mockFn);","handlingStrategy":"type-guard","validationCode":"const d = Object.getOwnPropertyDescriptor(obj, propertyKey);\nif (d && typeof d.value === 'function') {\n  jest.spyOn(obj, propertyKey).mockImplementation(value as any);\n} else {\n  jest.replaceProperty(obj, propertyKey, value);\n}","typeGuard":"const isFunctionValue = (o: object, k: PropertyKey): boolean => {\n  const d = Object.getOwnPropertyDescriptor(o, k);\n  return !!d && typeof d.value === 'function';\n};","tryCatchPattern":null,"preventionTips":["Use spyOn for function members and replaceProperty for value members.","Check typeof obj.prop === 'function' before picking the API.","Keep a cheat-sheet of jest spy vs replace vs module mock decision rules."],"tags":["mock","replace-property","spy","function"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}