{"record":{"id":"214c84e7842e273c","repo":"jestjs/jest","slug":"cannot-replace-the-string-propertykey-proper-214c84","errorCode":null,"errorMessage":"Cannot replace the `${String(propertyKey)}` property because it has a setter. Use `jest.spyOn(object, '${String(propertyKey)}', 'set').mockReturnValue(value)` instead.","messagePattern":"Cannot replace the `(.+?)` property because it has a setter\\. Use `jest\\.spyOn\\(object, '(.+?)', 'set'\\)\\.mockReturnValue\\(value\\)` instead\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-mock/src/index.ts","lineNumber":1500,"sourceCode":"    }\n    if (!descriptor.configurable) {\n      throw new Error(\n        `Property \\`${String(propertyKey)}\\` is not declared configurable`,\n      );\n    }\n\n    if (descriptor.get !== undefined) {\n      throw new Error(\n        `Cannot replace the \\`${String(\n          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","sourceCodeStart":1482,"sourceCodeEnd":1518,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-mock/src/index.ts#L1482-L1518","documentation":"Thrown by jest.replaceProperty when the descriptor has a setter. Replacing it would drop the setter side and break write semantics, so Jest points you to spyOn with accessType 'set' to wrap the setter instead.","triggerScenarios":"jest.replaceProperty(obj,'x',v) where x is declared with a setter (Object.defineProperty({set:...}) or a class set accessor).","commonSituations":"Class setter properties; validated write-only fields; framework objects with side-effecting setters.","solutions":["Use jest.spyOn(obj,'x','set').mockImplementation(fn) to intercept writes.","If you genuinely need to replace the whole property, redefine it without a setter first (only if configurable).","Use module-level jest.mock for owned code."],"exampleFix":"// before\njest.replaceProperty(obj, 'count', 5); // count has a setter\n// after\njest.spyOn(obj, 'count', 'set').mockImplementation(() => {});","handlingStrategy":"validation","validationCode":"const d = Object.getOwnPropertyDescriptor(obj, propertyKey);\nif (d?.set) {\n  jest.spyOn(obj, propertyKey, 'set').mockImplementation(fn);\n} else {\n  jest.replaceProperty(obj, propertyKey, value);\n}","typeGuard":"const hasSetter = (o: object, k: PropertyKey): boolean =>\n  Object.getOwnPropertyDescriptor(o, k)?.set !== undefined;","tryCatchPattern":null,"preventionTips":["Check the descriptor's set before choosing replaceProperty.","Use spyOn(obj, prop, 'set') for setter-backed writes.","Inspect class accessor declarations before mocking."],"tags":["mock","replace-property","accessor","setter"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}