{"record":{"id":"9492fd3274db2b09","repo":"jestjs/jest","slug":"spyon-could-not-find-an-object-to-spy-upon-for","errorCode":null,"errorMessage":"<spyOn> : could not find an object to spy upon for ${methodName}()\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":88,"sourceCode":"    accessType: keyof PropertyDescriptor,\n  ) => Spy;\n\n  constructor({\n    currentSpies = () => [],\n  }: {\n    currentSpies?: () => Array<Spy>;\n  } = {}) {\n    this.allowRespy = function (allow) {\n      this.respy = allow;\n    };\n\n    this.spyOn = (obj, methodName, accessType) => {\n      if (accessType) {\n        return this._spyOnProperty(obj, methodName, accessType);\n      }\n\n      if (obj === void 0) {\n        throw new Error(\n          getErrorMsg(\n            `could not find an object to spy upon for ${methodName}()`,\n          ),\n        );\n      }\n\n      if (methodName === void 0) {\n        throw new Error(getErrorMsg('No method name supplied'));\n      }\n\n      if (obj[methodName] === void 0) {\n        throw new Error(getErrorMsg(`${methodName}() method does not exist`));\n      }\n\n      if (obj[methodName] && isSpy(obj[methodName])) {\n        if (this.respy) {\n          return obj[methodName];\n        } else {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-jasmine2/src/jasmine/spyRegistry.ts#L70-L106","documentation":"Thrown by SpyRegistry.spyOn when the target object argument is undefined (spyRegistry.ts:88). spyOn requires a real object instance whose method will be replaced; a missing import, a not-yet-initialised module, or a destructuring that yields undefined means there is nothing to attach the spy to.","triggerScenarios":"spyOn(undefined, 'fetch'), spyOn(fs, 'readFile') where fs was never imported, spyOn(SomeClass.prototype, 'method') before the class is defined, or spyOn(obj, 'method') where obj is conditionally undefined.","commonSituations":"ESM/CJS interop where the default import is wrapped and the named member is undefined; importing a side-effect-only module that exports nothing; spying on a prototype of a class defined in another file with circular import timing; mock factory returning undefined.","solutions":["Verify the import path and shape: log `typeof obj` immediately before spyOn; ensure it is an object.","For ESM interop, use `import * as Namespace from 'mod'` and spy on Namespace.member, or call jest.unstable_mockModule correctly.","For prototype spies, confirm the class is fully defined: spyOn(MyClass.prototype, 'method').","If the object is optional, guard: if (obj) spyOn(obj, 'method');."],"exampleFix":"// before\nimport {fs} from './fs';\nspyOn(fs, 'readFile'); // fs is undefined\n// after\nimport * as fs from 'node:fs';\nspyOn(fs, 'readFile');","handlingStrategy":"validation","validationCode":"if (obj === undefined || obj === null) {\n  throw new Error('spyOn: target object is undefined; check the import');\n}\nspyOn(obj, 'method');","typeGuard":"const isSpyTarget = (v: unknown): v is Record<string, any> =>\n  v !== null && v !== undefined && typeof v === 'object';","tryCatchPattern":"try {\n  spyOn(obj, 'method');\n} catch (e) {\n  if (e.message.includes('could not find an object')) {\n    // log the import source, then rethrow or skip\n  }\n  throw e;\n}","preventionTips":["Log `typeof obj` immediately before spyOn.","For ESM, use namespace imports and spy on members.","Confirm prototypes are loaded before spying on them."],"tags":["jest","spyon","mocking","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"}