jestjs/jest · error · Error

Property `${String(propertyKey)}` does not exist in the prov

Error message

Property `${String(propertyKey)}` does not exist in the provided object

What it means

Thrown by the internal _spyOnProperty (reached when spyOn is called with a third 'get'/'set' accessType) when no property descriptor is found anywhere on the object or its prototype chain. The accessor-based spy needs an existing descriptor to replace.

Source

Thrown at packages/jest-mock/src/index.ts:1386

    object: T,
    propertyKey: keyof T,
    accessType: 'get' | 'set',
  ): MockInstance {
    const isPropertyOwner = Object.prototype.hasOwnProperty.call(
      object,
      propertyKey,
    );

    let descriptor = Object.getOwnPropertyDescriptor(object, propertyKey);
    let proto = Object.getPrototypeOf(object);

    while (!descriptor && proto !== null) {
      descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
      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}`,
      );

View on GitHub (pinned to 8e6d128e4a)

Solutions

  1. Confirm the property exists with Object.getOwnPropertyDescriptor and walk the prototype chain.
  2. If it is a plain value, drop the accessType and use plain spyOn or jest.replaceProperty.
  3. Spy on the prototype object that actually defines the accessor.

Example fix

// before
jest.spyOn(obj, 'value', 'get'); // no such accessor
// after
const desc = Object.getOwnPropertyDescriptor(obj, 'value');
if (desc?.get) jest.spyOn(obj, 'value', 'get');
else jest.replaceProperty(obj, 'value', newValue);
Defensive patterns

Strategy: validation

Validate before calling

const desc = Object.getOwnPropertyDescriptor(obj, propertyKey)
  ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), propertyKey);
if (!desc) {
  throw new Error(`No descriptor for ${String(propertyKey)}; not an accessor`);
}
jest.spyOn(obj, propertyKey, accessType);

Type guard

const hasAccessorDescriptor = (o: object, k: PropertyKey): boolean => {
  let d = Object.getOwnPropertyDescriptor(o, k);
  let p = Object.getPrototypeOf(o);
  while (!d && p !== null) { d = Object.getOwnPropertyDescriptor(p, k); p = Object.getPrototypeOf(p); }
  return !!d && (!!d.get || !!d.set);
};

Prevention

When it happens

Trigger: jest.spyOn(obj,'missing','get'); jest.spyOn(obj,'noAccessor','set') where the property does not exist on obj or any prototype.

Common situations: Misspelled accessor name; the accessor is defined on a different prototype level than expected; the property is a plain value (no get/set) so the descriptor has no accessor to spy on via this path.

Related errors


AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10). Data as JSON: /api/errors/7017aa5c099fc65f. Report an issue: GitHub.