jestjs/jest · error · Error

Property `${propertyKey}` does not exist in the provided obj

Error message

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

What it means

Thrown by the internal _spyOnProperty (the path taken when spyOn is called with a third 'get'/'set' argument) when no property descriptor for propertyKey is found on the object or anywhere up its prototype chain. This is the accessor equivalent of error 145: the named property simply does not exist as a defined accessor.

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 f49721c78e)

Solutions

  1. Verify the accessor exists at runtime: const d = Object.getOwnPropertyDescriptor(obj, 'key') || Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'key'); console.log(d).
  2. Fix the property name (case, spelling) against the current version of the library.
  3. If you only need to replace a plain value (not an accessor), drop the third arg and use spyOn without 'get'/'set', or use replaceProperty.

Example fix

// before
jest.spyOn(store, 'state', 'get'); // 'state' is not defined as a getter
// after
jest.spyOn(store, 'getState'); // it's a method, not an accessor
Defensive patterns

Strategy: validation

Validate before calling

function findDescriptor(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;
}
if (!findDescriptor(obj, key)) {
  throw new Error(`accessor '${String(key)}' does not exist`);
}
jest.spyOn(obj, key, 'get');

Type guard

const hasAccessor = (o: object, k: PropertyKey, t: 'get' | 'set') => {
  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 && d[t]);
};

if (hasAccessor(obj, key, 'get')) {
  jest.spyOn(obj, key, 'get');
}

Prevention

When it happens

Trigger: jest.spyOn(obj, 'missing', 'get'); jest.spyOn(obj, 'missing', 'set'); spying on an accessor before the class that defines it has been loaded; misspelled accessor name; the accessor was renamed in a library upgrade.

Common situations: Library version bump renamed/removed a getter; the accessor is defined via a mixin that hasn't been applied yet; typo in the property name.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/2c275c724bab6fb5.json. Report an issue: GitHub.