jestjs/jest · error · Error

Cannot replace the `${String(propertyKey)}` property because

Error message

Cannot replace the `${String(propertyKey)}` property because it has a setter. Use `jest.spyOn(object, '${String(propertyKey)}', 'set').mockReturnValue(value)` instead.

What it means

Thrown by jest.replaceProperty when the descriptor has a setter. Replacing it would drop the setter side and break write semantics, so Jest points you to spyOn with accessType 'set' to wrap the setter instead.

Source

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

    }
    if (!descriptor.configurable) {
      throw new Error(
        `Property \`${String(propertyKey)}\` is not declared configurable`,
      );
    }

    if (descriptor.get !== undefined) {
      throw new Error(
        `Cannot replace the \`${String(
          propertyKey,
        )}\` property because it has a getter. Use \`jest.spyOn(object, '${String(
          propertyKey,
        )}', 'get').mockReturnValue(value)\` instead.`,
      );
    }

    if (descriptor.set !== undefined) {
      throw new Error(
        `Cannot replace the \`${String(
          propertyKey,
        )}\` property because it has a setter. Use \`jest.spyOn(object, '${String(
          propertyKey,
        )}', 'set').mockReturnValue(value)\` instead.`,
      );
    }

    if (typeof descriptor.value === 'function') {
      throw new TypeError(
        `Cannot replace the \`${String(
          propertyKey,
        )}\` property because it is a function. Use \`jest.spyOn(object, '${String(
          propertyKey,
        )}')\` instead.`,
      );
    }

View on GitHub (pinned to 8e6d128e4a)

Solutions

  1. Use jest.spyOn(obj,'x','set').mockImplementation(fn) to intercept writes.
  2. If you genuinely need to replace the whole property, redefine it without a setter first (only if configurable).
  3. Use module-level jest.mock for owned code.

Example fix

// before
jest.replaceProperty(obj, 'count', 5); // count has a setter
// after
jest.spyOn(obj, 'count', 'set').mockImplementation(() => {});
Defensive patterns

Strategy: validation

Validate before calling

const d = Object.getOwnPropertyDescriptor(obj, propertyKey);
if (d?.set) {
  jest.spyOn(obj, propertyKey, 'set').mockImplementation(fn);
} else {
  jest.replaceProperty(obj, propertyKey, value);
}

Type guard

const hasSetter = (o: object, k: PropertyKey): boolean =>
  Object.getOwnPropertyDescriptor(o, k)?.set !== undefined;

Prevention

When it happens

Trigger: jest.replaceProperty(obj,'x',v) where x is declared with a setter (Object.defineProperty({set:...}) or a class set accessor).

Common situations: Class setter properties; validated write-only fields; framework objects with side-effecting setters.

Related errors


AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10). Data as JSON: /api/errors/214c84e7842e273c. Report an issue: GitHub.