{"record":{"id":"ec5235e2215c8cf8","repo":"jestjs/jest","slug":"property-string-propertykey-is-not-declared","errorCode":null,"errorMessage":"Property `${String(propertyKey)}` is not declared configurable","messagePattern":"Property `(.+?)` is not declared configurable","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-mock/src/index.ts","lineNumber":1394,"sourceCode":"\n    let descriptor = Object.getOwnPropertyDescriptor(object, propertyKey);\n    let proto = Object.getPrototypeOf(object);\n\n    while (!descriptor && proto !== null) {\n      descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);\n      proto = Object.getPrototypeOf(proto);\n    }\n\n    if (!descriptor) {\n      throw new Error(\n        `Property \\`${String(\n          propertyKey,\n        )}\\` does not exist in the provided object`,\n      );\n    }\n\n    if (!descriptor.configurable) {\n      throw new Error(\n        `Property \\`${String(propertyKey)}\\` is not declared configurable`,\n      );\n    }\n\n    if (!descriptor[accessType]) {\n      throw new Error(\n        `Property \\`${String(\n          propertyKey,\n        )}\\` does not have access type ${accessType}`,\n      );\n    }\n\n    const original = descriptor[accessType];\n\n    if (!this.isMockFunction(original)) {\n      if (typeof original !== 'function') {\n        throw new TypeError(\n          `Cannot spy on the ${String(","sourceCodeStart":1376,"sourceCodeEnd":1412,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-mock/src/index.ts#L1376-L1412","documentation":"Thrown by _spyOnProperty when the located descriptor has configurable:false. Redefining a non-configurable accessor is forbidden by the JS engine, so Jest cannot install the spy.","triggerScenarios":"jest.spyOn(obj,'x','get') on a frozen object or a property declared non-configurable (some native/DOM/class fields, Object.freeze'd targets).","commonSituations":"Spying on built-in or host object accessors; objects sealed/frozen by a library; class fields emitted with configurable:false; React/internal framework objects.","solutions":["Spy on a wrapper/proxy you control instead of the frozen object.","Redefine the property as configurable before spying (only possible if it was configurable originally).","Mock at the module level (jest.mock) rather than the property level."],"exampleFix":"// before\njest.spyOn(frozenObj, 'x', 'get'); // configurable:false\n// after\njest.mock('./config', () => ({...})); // mock the module instead","handlingStrategy":"validation","validationCode":"const d = Object.getOwnPropertyDescriptor(obj, propertyKey);\nif (d && !d.configurable) {\n  // mock at module level instead\n  jest.mock(modulePath, factory);\n} else {\n  jest.spyOn(obj, propertyKey, accessType);\n}","typeGuard":"const isConfigurable = (o: object, k: PropertyKey): boolean =>\n  Object.getOwnPropertyDescriptor(o, k)?.configurable === true;","tryCatchPattern":null,"preventionTips":["Avoid spying on frozen/sealed objects or host globals.","Prefer module-level jest.mock for non-configurable internals.","Wrap external objects in your own configurable proxy for testing."],"tags":["spy","mock","accessor","configurable"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}