{"id":"c111874466c7795f","repo":"jestjs/jest","slug":"cannot-use-replaceproperty-on-a-primitive-value","errorCode":null,"errorMessage":"Cannot use replaceProperty on a primitive value; ${typeOfObject} given","messagePattern":"Cannot use replaceProperty on a primitive value; (.+?) given","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-mock/src/index.ts","lineNumber":1459,"sourceCode":"        // @ts-expect-error - wrong context\n        return original.apply(this, arguments);\n      });\n    }\n\n    Object.defineProperty(object, propertyKey, descriptor);\n    return descriptor[accessType] as Mock;\n  }\n\n  replaceProperty<T extends object, K extends keyof T>(\n    object: T,\n    propertyKey: K,\n    value: T[K],\n  ): Replaced<T[K]> {\n    if (\n      object == null ||\n      (typeof object !== 'object' && typeof object !== 'function')\n    ) {\n      throw new Error(\n        `Cannot use replaceProperty on a primitive value; ${this._typeOf(\n          object,\n        )} given`,\n      );\n    }\n\n    if (propertyKey == null) {\n      throw new Error('No property name supplied');\n    }\n\n    let descriptor = Object.getOwnPropertyDescriptor(object, propertyKey);\n    let proto = Object.getPrototypeOf(object);\n    while (!descriptor && proto !== null) {\n      descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);\n      proto = Object.getPrototypeOf(proto);\n    }\n    if (!descriptor) {\n      throw new Error(","sourceCodeStart":1441,"sourceCodeEnd":1477,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-mock/src/index.ts#L1441-L1477","documentation":"Thrown by jest.replaceProperty when the first argument is null/undefined or a primitive (the same guard as spyOn: object == null || typeof !== 'object' && typeof !== 'function'). replaceProperty needs to redefine a data property on the target, which is impossible on primitives because they hold no extensible own property slots.","triggerScenarios":"jest.replaceProperty(42, 'x', 5); jest.replaceProperty('hi', 'length', 2); jest.replaceProperty(null, 'x', 1); jest.replaceProperty(undefined, 'x', 1). Frequently appears when the object came from a lookup that returned undefined.","commonSituations":"Optional chaining producing undefined that is then passed in: jest.replaceProperty(maybeObj.value, 'k', v); refactor that turned a singleton object into a primitive constant; wrong variable referenced.","solutions":["Confirm the first argument is the object that owns the property: log it and its typeof before the call.","Replace the primitive at its source — mutate the container object's property instead.","If the holder may be undefined, guard: if (obj) jest.replaceProperty(obj, 'k', v)."],"exampleFix":"// before\njest.replaceProperty(Config.retryMs, 'value', 100); // retryMs is 500 (number)\n// after\njest.replaceProperty(Config, 'retryMs', 100);","handlingStrategy":"type-guard","validationCode":"if (target == null || (typeof target !== 'object' && typeof target !== 'function')) {\n  throw new Error(`replaceProperty target must be object/function, got ${typeof target}`);\n}\njest.replaceProperty(target, 'key', value);","typeGuard":"const isReplaceable = (v: unknown): v is object | ((...a: any[]) => any) =>\n  v != null && (typeof v === 'object' || typeof v === 'function');\n\nif (isReplaceable(target)) {\n  jest.replaceProperty(target, 'key', value);\n}","tryCatchPattern":null,"preventionTips":["Pass the holder object, not one of its primitive fields.","Guard against undefined holders from optional chains.","Log the target before calling to confirm shape."],"tags":["jest-mock","replaceproperty","type-error","primitives"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}