Fix 'TypeError: Attempted to assign to readonly property'

By

Learn how to fix the TypeError: Attempted to assign to readonly property in JavaScript, caused by mutating a string you forgot to pass to JSON.parse() first.

~~~

This error means you tried to change a value JavaScript considers read-only. In my case, I was assigning a property to a string I forgot to pass to JSON.parse() first. Strings are immutable, so the assignment failed.

Here’s the full story. I was doing something in my Next.js codebase when I ran into this problem:

TypeError: Attempted to assign to readonly property

Weird! After a bit of debugging I found the problem. It had nothing to do with Next.js, it can happen in any JavaScript codebase.

What caused the error?

I had a column in my database where I stored data as JSON.

In my code I was updating this JSON object using the dot syntax, like data.name = 'Flavio'. But I forgot to call JSON.parse() before doing so.

data was not an object. It was a string!

Strings are immutable in JavaScript. We can’t update them once defined. Here’s the smallest way to reproduce the error:

'use strict'

const data = '{"name":"Flavio"}'
data.name = 'Flavio Copes'

The exact message depends on the JavaScript engine. Safari says “Attempted to assign to readonly property”. Node.js and Chrome say “Cannot create property ‘name’ on string”. Same problem, different wording.

Notice the 'use strict' line. Without strict mode, the assignment fails silently: no error, and your data never changes. That’s worse, because the bug hides. ES modules always run in strict mode, so in a modern codebase you get the error right away.

The fix

Call JSON.parse() before updating the object:

const data = JSON.parse(row.metadata)
data.name = 'Flavio Copes'

And remember the reverse step: call JSON.stringify(data) before writing the value back to the database. Otherwise you’ll store [object Object] or hit a serialization error, depending on your database driver.

Other ways to get this error

You’ll see the same message when writing to a frozen object:

'use strict'

const config = Object.freeze({ port: 3000 })
config.port = 4000

Safari reports “Attempted to assign to readonly property” here too. Node.js says “Cannot assign to read only property ‘port’ of object”.

So when you see this error, check two things: is the value actually an object (and not a string), and did some code freeze it? In my experience, the forgotten JSON.parse() is the most common cause.

~~~

Related posts about js: