jestjs/jest · error · Error

Property `${methodKey}` does not exist in the provided objec

Error message

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

What it means

Thrown by jest.spyOn when object[methodKey] is falsy (the !original check). This means the property is undefined, null, 0, false, or '' at the moment spyOn reads it. Most commonly the property simply does not exist on the object or its prototype chain as a value (it may be an accessor, or the method is not implemented). Note this checks the runtime value, not the type signature — a method that exists in types but is undefined at runtime trips this.

Source

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

      (typeof object !== 'object' && typeof object !== 'function')
    ) {
      throw new Error(
        `Cannot use spyOn on a primitive value; ${this._typeOf(object)} given`,
      );
    }

    if (methodKey == null) {
      throw new Error('No property name supplied');
    }

    if (accessType) {
      return this._spyOnProperty(object, methodKey, accessType);
    }

    const original = object[methodKey];

    if (!original) {
      throw new Error(
        `Property \`${String(
          methodKey,
        )}\` does not exist in the provided object`,
      );
    }

    if (!this.isMockFunction(original)) {
      if (typeof original !== 'function') {
        throw new TypeError(
          `Cannot spy on the \`${String(
            methodKey,
          )}\` property because it is not a function; ${this._typeOf(
            original,
          )} given instead.${
            typeof original === 'object'
              ? ''
              : ` If you are trying to mock a property, use \`jest.replaceProperty(object, '${String(
                  methodKey,

View on GitHub (pinned to f49721c78e)

Solutions

  1. Confirm the property exists at runtime: console.log(typeof obj.methodName) and check spelling/casing.
  2. If the method is an accessor, pass the access type: jest.spyOn(obj, 'prop', 'get').
  3. If it is a non-function value you want to replace, use jest.replaceProperty(obj, 'prop', value).
  4. Ensure the spy runs after the module under test has fully loaded its exports.

Example fix

// before
jest.spyOn(fs.promises, 'readfile'); // wrong casing -> undefined
// after
jest.spyOn(fs.promises, 'readFile');
Defensive patterns

Strategy: validation

Validate before calling

if (!obj[methodKey]) {
  throw new Error(`Property '${String(methodKey)}' not found on object before spying`);
}
jest.spyOn(obj, methodKey);

Type guard

function hasMethod<T extends object, K extends keyof T>(
  obj: T,
  k: K,
): obj is T & Record<K, Function> {
  return typeof obj[k] === 'function';
}

if (hasMethod(service, 'send')) {
  jest.spyOn(service, 'send');
}

Prevention

When it happens

Trigger: jest.spyOn(obj, 'nope') where obj has no 'nope'; spying on a method that lives on the prototype but the instance shadows it with undefined; spying before the module has populated the method (import order); method name typo (jest.spyOn(fs, 'readfile') instead of 'readFile').

Common situations: Case mismatch in the method name; tree-shaking removed the method; the method is a getter not a value (use the third arg 'get'); ESM live bindings where the export is not yet initialized when the spy runs.

Related errors


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