How to fix Cannot assign to read-only property of an object in strict mode in React

ReactINTERMEDIATEMEDIUMUpdated Dec 10, 2025· 177 views

React ships in JavaScript strict mode, so assigning to a property that has been frozen or defined as non-writable (state, props, refs, DOM nodes) throws a TypeError. The fix is to treat data as immutable and avoid touching read-only descriptors.

Quick fix

Fixes Cannot assign to read-only property of an object in strict mode

const descriptor = Object.getOwnPropertyDescriptor(targetObject, 'propertyName');
console.log(descriptor); // writable: false warns you that you cannot assign
  1. Inspect the read-only property descriptor
  2. Avoid mutating state or props directly
  3. Copy or thaw frozen objects
  4. Use mutable refs when assigning to current
react — error
const descriptor = Object.getOwnPropertyDescriptor(targetObject, 'propertyName');
console.log(descriptor); // writable: false warns you that you cannot assign
Cannot assign to read-only property of an object in strict mode

What this error means

JavaScript strict mode throws this TypeError whenever code tries to mutate a property whose descriptor has 'writable: false', or when the object was frozen via Object.freeze() or Object.defineProperty(). React bundles always use strict mode, and many dev builds freeze props, refs, or state objects to detect mutations early. Writing to those read-only slots therefore fails with this error, which most often points at props/state updates, RefObject.current assignments, or DOM properties that React expects you to treat as immutable.

Typical symptoms

  • Browser console: TypeError: Cannot assign to read only property "current" of object "#<Object>"
  • StrictMode renders twice in development and immediately throws when a mutation happens
  • Error surfaces when updating React state or props directly instead of creating a new object/array
  • TypeScript shows "Cannot assign to 'current' because it is a read-only property" during compilation or lint checks
  • Third-party libraries such as Redux Toolkit or React Hook Form freeze data in dev mode, causing this error on attempted mutations
  • The crash only appears in development, because production bundles often omit the freezing helpers

Common causes

  1. Mutating React state or props directly instead of copying and passing new objects to setState/setters
  2. Attempting to write to an object or array that was frozen with Object.freeze() (Redux Toolkit, Immer, or manual freezes)
  3. Defining a property with Object.defineProperty or Object.defineProperties without writable: true
  4. Assigning to useRef’s current when the ref is typed as React.RefObject rather than React.MutableRefObject
  5. Writing a string over DOM properties such as element.style or window.event that are effectively read-only in strict mode
  6. Modifying props passed from a parent component or a library hook that exposes a read-only API

How to fix "Cannot assign to read-only property of an object in strict mode"

1Inspect the read-only property descriptor

Check the exact property reported by the error and log its descriptor to confirm it is not writable:

javascript
const descriptor = Object.getOwnPropertyDescriptor(targetObject, 'propertyName');
console.log(descriptor); // writable: false warns you that you cannot assign
2Avoid mutating state or props directly

React works best when state/props are treated as immutable. When you need to change nested data, create a shallow copy before calling the updater:

javascript
// BAD
user.address.city = 'Berlin';
setUser(user);

// GOOD
setUser(prev => ({
  ...prev,
  address: { ...prev.address, city: 'Berlin' }
}));

// For arrays
setItems(prev => [...prev, newItem]);
3Copy or thaw frozen objects

Libraries or dev-only safeguards freeze objects to catch accidental mutations. Create a mutable copy before changing them:

javascript
const mutable = { ...frozenObject };
mutable.name = 'Alice';

const deepCopy = structuredClone(frozenObject);
deepCopy.items.push('x');

Use helper libraries such as Immer or lodash clonedeep when necessary, and never mutate the frozen value in-place.

4Use mutable refs when assigning to current

In TypeScript, useRef returns a RefObject whose current is readonly. Cast to MutableRefObject or declare the ref type explicitly:

typescript
// BAD
const inputRef = useRef<HTMLInputElement>(null);
inputRef.current = otherElement; // compile-time error + runtime error if strict mode rejects it

// GOOD
const inputRef = useRef<HTMLInputElement | null>(null);
const mutableRef = inputRef as MutableRefObject<HTMLInputElement | null>;
mutableRef.current = otherElement;

Or use a callback ref so React controls assignment without manual writes.

5Redefine properties if you control their descriptor

If you are authoring the object, define the property with writable: true:

javascript
Object.defineProperty(obj, 'name', {
  value: 'Jane',
  writable: true,
  configurable: true
});

If the property is frozen via Object.freeze(), create a new object instead of reusing the frozen reference.

6Avoid reassigning read-only DOM APIs

Don't overwrite DOM APIs that are read-only in strict mode. Instead set individual properties:

javascript
// BAD
div.style = 'color: blue;'; // Strict mode turns this into a read-only assignment

// GOOD
div.style.cssText = 'color: blue;';
div.style.setProperty('font-size', '14px');

React's style prop already maps to the proper setters.

7Let libraries manage refs and props

Hooks such as React Hook Form expect you to hand them refs rather than editing the underlying objects yourself. If the library exposes a readonly ref:

javascript
register('field', { ref: refElement });
// avoid: refElement.current = anotherElement;

Call the library API (setValue, register, etc.) instead of reassigning internal references.

Advanced notes

StrictMode in React: React's StrictMode intentionally double-invokes renderers and mount lifecycles to reveal side effects, so once you mutate a frozen object the error appears almost immediately in development.

Dev-only Freezing: Redux Toolkit, Immer, and other libraries freeze state objects only in development. That is why the error might only show up locally even though production works: the read-only guard is removed for performance.

Immutable Updates Improve Performance: Immutable updates keep shallow equality checks fast and avoid confusing bugs. Embrace immutability helpers (spread, structuredClone, immer/produce) instead of mutating in place.

Frequently asked questions

What does "Cannot assign to read-only property of an object in strict mode" mean?
defineProperty(). React bundles always use strict mode, and many dev builds freeze props, refs, or state objects to detect mutations early. current assignments, or DOM properties that React expects you to treat as immutable.
How do I fix "Cannot assign to read-only property of an object in strict mode"?
React ships in JavaScript strict mode, so assigning to a property that has been frozen or defined as non-writable (state, props, refs, DOM nodes) throws a TypeError. The fix is to treat data as immutable and avoid touching read-only descriptors.
What causes "Cannot assign to read-only property of an object in strict mode"?
Mutating React state or props directly instead of copying and passing new objects to setState/setters Attempting to write to an object or array that was frozen with Object.freeze() (Redux Toolkit, Immer, or manual freezes) Defining a property with Object.defineProperty or Object.defineProperties without writable: true
Is the "Cannot assign to read-only property of an object in strict mode" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading