{"id":"14585e7ff1e49ea3","repo":"jestjs/jest","slug":"property-propertykey-is-not-declared-configur","errorCode":null,"errorMessage":"Property `${propertyKey}` is not declared configurable","messagePattern":"Property `(.+?)` is not declared configurable","errorType":"exception","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/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-mock/src/index.ts#L1376-L1412","documentation":"Thrown by _spyOnProperty when the descriptor for propertyKey is found but descriptor.configurable is false. JavaScript forbids redefining a non-configurable accessor, so the mocker cannot install a spy. Native properties and some frozen/sealed objects commonly have configurable:false.","triggerScenarios":"jest.spyOn([], 'length', 'get'); (Array.prototype.length is non-configurable); spying on a property of an Object.freeze'd object; spying on a built-in like Math.PI accessor; libraries that define hard-coded non-configurable accessors via Object.defineProperty(obj, k, {configurable:false, get}).","commonSituations":"Trying to mock readonly length of arrays/strings; targeting an object the application froze for safety; a third-party class that locks down its properties.","solutions":["Replace the target with a configurable stand-in: shallow-copy the object or wrap it before spying.","Spy at the prototype level if the accessor is configurable there (or re-define it as configurable before spying, if you control the code).","If you do not own the object, refactor the test to inject a seam (dependency injection) so you can pass a mockable instance."],"exampleFix":"// before\njest.spyOn(frozenStore, 'version', 'get'); // frozenStore is Object.freeze'd\n// after\nconst store = {...frozenStore}; Object.defineProperty(store, 'version', { configurable: true, get: () => 2 }); jest.spyOn(store, 'version', 'get');","handlingStrategy":"validation","validationCode":"const d = Object.getOwnPropertyDescriptor(obj, key) ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), key);\nif (!d || !d.configurable) {\n  throw new Error(`'${String(key)}' is not configurable; spy on a copy instead`);\n}\njest.spyOn(obj, key, 'get');","typeGuard":"const isConfigurableAccessor = (o: object, k: PropertyKey, t: 'get' | 'set') => {\n  let d = Object.getOwnPropertyDescriptor(o, k);\n  let p = Object.getPrototypeOf(o);\n  while (!d && p) { d = Object.getOwnPropertyDescriptor(p, k); p = Object.getPrototypeOf(p); }\n  return !!(d?.configurable && d[t]);\n};","tryCatchPattern":null,"preventionTips":["Don't try to spy on frozen/sealed objects directly — operate on a copy.","Avoid spying on built-in non-configurable properties like Array length.","Inject a mockable seam via dependency injection when you don't own the object."],"tags":["jest-mock","spyon","accessor","configurable","frozen"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}