jestjs/jest · error · Error
Cannot replace the `${propertyKey}` property because it has
Error message
Cannot replace the `${propertyKey}` property because it has a setter. Use `jest.spyOn(object, '${propertyKey}', 'set').mockReturnValue(value)` instead. What it means
Thrown by jest.replaceProperty when the descriptor has a setter (descriptor.set !== undefined). The same rationale as error 155: replaceProperty cannot replace an accessor-backed property, and the message directs you to jest.spyOn(object, 'key', 'set').mockReturnValue(value).
Source
Thrown at packages/jest-mock/src/index.ts:1500
}
if (!descriptor.configurable) {
throw new Error(
`Property \`${String(propertyKey)}\` is not declared configurable`,
);
}
if (descriptor.get !== undefined) {
throw new Error(
`Cannot replace the \`${String(
propertyKey,
)}\` property because it has a getter. Use \`jest.spyOn(object, '${String(
propertyKey,
)}', 'get').mockReturnValue(value)\` instead.`,
);
}
if (descriptor.set !== undefined) {
throw new Error(
`Cannot replace the \`${String(
propertyKey,
)}\` property because it has a setter. Use \`jest.spyOn(object, '${String(
propertyKey,
)}', 'set').mockReturnValue(value)\` instead.`,
);
}
if (typeof descriptor.value === 'function') {
throw new TypeError(
`Cannot replace the \`${String(
propertyKey,
)}\` property because it is a function. Use \`jest.spyOn(object, '${String(
propertyKey,
)}')\` instead.`,
);
}
View on GitHub (pinned to f49721c78e)
Solutions
- Use jest.spyOn(object, 'key', 'set') to intercept assignments and mockReturnValue if needed.
- If both get and set exist, decide which direction you need and spy on that one (or both).
- If you truly must replace the whole property, redefine it with Object.defineProperty first (if configurable).
Example fix
// before
jest.replaceProperty(form, 'email', 'a@b.com'); // email has a setter
// after
const spy = jest.spyOn(form, 'email', 'set');
form.email = 'a@b.com';
expect(spy).toHaveBeenCalledWith('a@b.com'); Defensive patterns
Strategy: validation
Validate before calling
const d = Object.getOwnPropertyDescriptor(obj, key) ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), key);
if (d && d.set) {
const spy = jest.spyOn(obj, key, 'set');
} else {
jest.replaceProperty(obj, key, value);
} Type guard
const isSetterProp = (o: object, k: PropertyKey) => {
let d = Object.getOwnPropertyDescriptor(o, k);
let p = Object.getPrototypeOf(o);
while (!d && p) { d = Object.getOwnPropertyDescriptor(p, k); p = Object.getPrototypeOf(p); }
return !!(d && typeof d.set === 'function');
};
if (isSetterProp(obj, key)) {
jest.spyOn(obj, key, 'set');
} else {
jest.replaceProperty(obj, key, value);
} Prevention
- Check the descriptor for 'set' before calling replaceProperty on assignable properties.
- Use spyOn(..., 'set') to validate or intercept assignments to setter-backed properties.
- Remember write-only properties have only 'set'.
When it happens
Trigger: jest.replaceProperty(obj, 'value', v) where value is backed by a set accessor (write-only or get/set pair); targeting a property of a class that declared set value(x){...}.
Common situations: Write-only credential setters; classes that validate on assignment via a setter; reactive frameworks that intercept assignment.
Related errors
- Cannot replace the `${propertyKey}` property because it has
- Cannot spy on the `${methodKey}` property because it is not
- Property `${propertyKey}` does not exist in the provided obj
- Property `${propertyKey}` is not declared configurable
- Property `${propertyKey}` does not have access type ${access
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/e4fa846b6ed10753.json.
Report an issue: GitHub.