{"record":{"id":"6e12a6b48fe84d43","repo":"jestjs/jest","slug":"spyon-no-property-name-supplied-usage-spyon","errorCode":null,"errorMessage":"<spyOn> : No property name supplied\nUsage: spyOn(<object>, <methodName>)","messagePattern":"<spyOn> : No property name supplied\nUsage: spyOn\\(<object>, <methodName>\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-jasmine2/src/jasmine/spyRegistry.ts","lineNumber":163,"sourceCode":"        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) {\n        throw new Error(getErrorMsg(`${propertyName} property does not exist`));\n      }\n\n      if (!descriptor.configurable) {\n        throw new Error(\n          getErrorMsg(`${propertyName} is not declared configurable`),\n        );\n      }","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-jasmine2/src/jasmine/spyRegistry.ts#L145-L181","documentation":"Thrown by SpyRegistry._spyOnProperty when propertyName is falsy (spyRegistry.ts:162-164). The property name selects which accessor descriptor to replace; without it the registry cannot locate the getter/setter to spy on.","triggerScenarios":"spyOn(obj, undefined, 'get'), spyOn(obj, '', 'get'), spyOn(obj) with the accessType arg pushed out, or a dynamically-computed name that resolved to an empty string.","commonSituations":"Refactor that renamed the property but left the spy on the old name variable computed elsewhere; destructuring that lost the name; copy-paste of a spy template that omitted the second arg.","solutions":["Pass the literal property name: spyOn(obj, 'value', 'get').","If dynamic, validate first: if (!name) throw new Error('property name required'); spyOn(obj, name, 'get').","Type propertyName as keyof typeof obj to catch undefined at compile time.","Review auto-formatter output that may have dropped a line."],"exampleFix":"// before\nspyOn(obj, undefined, 'get');\n// after\nspyOn(obj, 'value', 'get');","handlingStrategy":"validation","validationCode":"if (!propertyName) {\n  throw new Error('spyOn property: propertyName is required');\n}\nspyOn(obj, propertyName, 'get');","typeGuard":"const isPropertyName = (v: unknown): v is string =>\n  typeof v === 'string' && v.length > 0;","tryCatchPattern":null,"preventionTips":["Pass a non-empty property name string.","Type propertyName as keyof typeof obj.","Review formatter output after refactors."],"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-14T05:17:10.506Z"}