{"record":{"id":"f59fdcd26d849c7e","repo":"jestjs/jest","slug":"spyon-could-not-find-an-object-to-spy-upon-for-f59fdc","errorCode":null,"errorMessage":"<spyOn> : could not find an object to spy upon for ${propertyName}\nUsage: spyOn(<object>, <methodName>)","messagePattern":"<spyOn> : could not find an object to spy upon for (.+?)\nUsage: spyOn\\(<object>, <methodName>\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-jasmine2/src/jasmine/spyRegistry.ts","lineNumber":155,"sourceCode":"        restoreStrategy = function () {\n          if (!delete obj[methodName]) {\n            obj[methodName] = originalMethod;\n          }\n        };\n      }\n\n      currentSpies().push({\n        restoreObjectToOriginalState: restoreStrategy,\n      } as Spy);\n\n      obj[methodName] = spiedMethod;\n\n      return spiedMethod;\n    };\n\n    this._spyOnProperty = function (obj, propertyName, accessType = 'get') {\n      if (!obj) {\n        throw new Error(\n          getErrorMsg(\n            `could not find an object to spy upon for ${propertyName}`,\n          ),\n        );\n      }\n\n      if (!propertyName) {\n        throw new Error(getErrorMsg('No property name supplied'));\n      }\n\n      let descriptor: PropertyDescriptor | undefined;\n      try {\n        descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);\n      } catch {\n        // IE 8 doesn't support `definePropery` on non-DOM nodes\n      }\n\n      if (!descriptor) {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-jasmine2/src/jasmine/spyRegistry.ts#L137-L173","documentation":"Thrown by SpyRegistry._spyOnProperty when the target object is falsy (spyRegistry.ts:154-159). This is the property-access variant of spyOn (invoked when an accessType like 'get'/'set' is supplied); it needs a real object whose property descriptor will be redefined.","triggerScenarios":"spyOn(undefined, 'prop', 'get'), spyOn(null, 'prop', 'set'), or spyOn(obj, 'prop', 'get') where obj was destructured to undefined via a bad import.","commonSituations":"Switching from spyOn to the accessor form without re-checking the import; mocking a module whose default export is undefined under ESM; spying on a property of a lazily-initialised singleton that has not yet been constructed.","solutions":["Confirm the object is defined before spying: expect(obj).toBeDefined(); spyOn(obj, 'prop', 'get').","Fix the import so the object resolves; for ESM use `import * as ns` and spy on ns.prop.","Guard: if (obj) spyOn(obj, 'prop', 'get');.","Run the test in isolation to rule out load-order issues."],"exampleFix":"// before\nspyOn(undefined, 'value', 'get');\n// after\nimport * as cfg from './config';\nspyOn(cfg, 'value', 'get');","handlingStrategy":"validation","validationCode":"if (!obj) {\n  throw new Error('spyOn property: target object is null/undefined; verify the import');\n}\nspyOn(obj, 'prop', 'get');","typeGuard":"const isObject = (v: unknown): v is Record<string, any> =>\n  v !== null && v !== undefined && typeof v === 'object';","tryCatchPattern":null,"preventionTips":["Verify the import resolves to an object before spying.","Use namespace imports for ESM modules.","Guard optional targets with if (obj)."],"tags":["jest","spyon","mocking","property-accessor","undefined","api-misuse"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}