jestjs/jest · error · Error
Property `${propertyKey}` does not have access type ${access
Error message
Property `${propertyKey}` does not have access type ${accessType} What it means
Thrown by _spyOnProperty when the descriptor exists and is configurable but lacks the requested accessType — i.e. you asked to spy 'get' on a write-only accessor (only has set), or 'set' on a read-only accessor (only has get). The check is !descriptor[accessType].
Source
Thrown at packages/jest-mock/src/index.ts:1400
proto = Object.getPrototypeOf(proto);
}
if (!descriptor) {
throw new Error(
`Property \`${String(
propertyKey,
)}\` does not exist in the provided object`,
);
}
if (!descriptor.configurable) {
throw new Error(
`Property \`${String(propertyKey)}\` is not declared configurable`,
);
}
if (!descriptor[accessType]) {
throw new Error(
`Property \`${String(
propertyKey,
)}\` does not have access type ${accessType}`,
);
}
const original = descriptor[accessType];
if (!this.isMockFunction(original)) {
if (typeof original !== 'function') {
throw new TypeError(
`Cannot spy on the ${String(
propertyKey,
)} property because it is not a function; ${this._typeOf(
original,
)} given instead.${
typeof original === 'object'
? ''View on GitHub (pinned to f49721c78e)
Solutions
- Spy on the access type the property actually defines: use 'get' for read-only, 'set' for write-only.
- Inspect the descriptor first: Object.getOwnPropertyDescriptor(obj, key) and check which of get/set are present.
- If you need to control both directions, redefine the property (if configurable) to have both, then spy on each.
Example fix
// before jest.spyOn(user, 'id', 'set'); // id is read-only // after jest.spyOn(user, 'id', 'get');
Defensive patterns
Strategy: validation
Validate before calling
const d = Object.getOwnPropertyDescriptor(obj, key);
if (!d || !d['get']) {
throw new Error(`'${String(key)}' has no getter; cannot spy with 'get'`);
}
jest.spyOn(obj, key, 'get'); Type guard
const hasAccessType = (o: object, k: PropertyKey, t: 'get' | 'set'): boolean => {
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[t] === 'function');
};
const access = hasAccessType(obj, key, 'get') ? 'get' : 'set';
jest.spyOn(obj, key, access); Prevention
- Inspect which of get/set the property actually exposes before spying.
- Remember read-only properties only have 'get', write-only only have 'set'.
- If you need both, redefine the property to include both directions (if configurable).
When it happens
Trigger: jest.spyOn(obj, 'readOnlyProp', 'set') where the property has only a getter; jest.spyOn(obj, 'writeOnlyProp', 'get') where it has only a setter. Common with computed properties that intentionally expose only one direction.
Common situations: Assuming every accessor is a full get/set pair; library design where a property is intentionally write-only (e.g. credentials) or read-only.
Related errors
- Property `${propertyKey}` does not exist in the provided obj
- Property `${propertyKey}` is not declared configurable
- Cannot spy on the ${propertyKey} property because it is not
- Cannot use spyOn on a primitive value; ${typeOfObject} given
- No property name supplied
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/126aa1148289086b.json.
Report an issue: GitHub.