jestjs/jest · error · Error

Cannot use replaceProperty on a primitive value; ${typeOfObj

Error message

Cannot use replaceProperty on a primitive value; ${typeOfObject} given

What it means

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.

Source

Thrown at packages/jest-mock/src/index.ts:1459

        // @ts-expect-error - wrong context
        return original.apply(this, arguments);
      });
    }

    Object.defineProperty(object, propertyKey, descriptor);
    return descriptor[accessType] as Mock;
  }

  replaceProperty<T extends object, K extends keyof T>(
    object: T,
    propertyKey: K,
    value: T[K],
  ): Replaced<T[K]> {
    if (
      object == null ||
      (typeof object !== 'object' && typeof object !== 'function')
    ) {
      throw new Error(
        `Cannot use replaceProperty on a primitive value; ${this._typeOf(
          object,
        )} given`,
      );
    }

    if (propertyKey == null) {
      throw new Error('No property name supplied');
    }

    let descriptor = Object.getOwnPropertyDescriptor(object, propertyKey);
    let proto = Object.getPrototypeOf(object);
    while (!descriptor && proto !== null) {
      descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
      proto = Object.getPrototypeOf(proto);
    }
    if (!descriptor) {
      throw new Error(

View on GitHub (pinned to f49721c78e)

Solutions

  1. Confirm the first argument is the object that owns the property: log it and its typeof before the call.
  2. Replace the primitive at its source — mutate the container object's property instead.
  3. If the holder may be undefined, guard: if (obj) jest.replaceProperty(obj, 'k', v).

Example fix

// before
jest.replaceProperty(Config.retryMs, 'value', 100); // retryMs is 500 (number)
// after
jest.replaceProperty(Config, 'retryMs', 100);
Defensive patterns

Strategy: type-guard

Validate before calling

if (target == null || (typeof target !== 'object' && typeof target !== 'function')) {
  throw new Error(`replaceProperty target must be object/function, got ${typeof target}`);
}
jest.replaceProperty(target, 'key', value);

Type guard

const isReplaceable = (v: unknown): v is object | ((...a: any[]) => any) =>
  v != null && (typeof v === 'object' || typeof v === 'function');

if (isReplaceable(target)) {
  jest.replaceProperty(target, 'key', value);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/c111874466c7795f.json. Report an issue: GitHub.