Last updated: Mar 7, 2024
Reading time·3 min

The JavaScript "TypeError: Cannot redefine property: X" occurs when you attempt to redefine a property that is not configurable.
To solve the error, set the configurable property to true when calling the
Object.defineProperty() method.

Here is an example of how the error occurs.
const obj = Object.create({}); Object.defineProperty(obj, 'site', {value: 'bobbyhadz.com'}); // ⛔️ TypeError: Cannot redefine property: site // at Function.defineProperty (<anonymous>) Object.defineProperty(obj, 'site', {value: 'google.com'});
The issue in the code sample is that by default, properties created using
Object.defineProperty() are not configurable.
In other words, they cannot be deleted or changed.
configurable property to trueTo solve the error, set the configurable property to true in the call to the
Object.defineProperty() method.
// ✅ Works as expected const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); console.log(obj.site); // 👉️ google.com

The Object.create() method creates a new object using an existing object as
its prototype.
The Object.defineProperty() method adds a new property to an object or
modifies an existing property on the object.
The method takes the following 3 arguments:
| Name | Description |
|---|---|
| obj | The object on which to define the property |
| prop | The name of the property |
| descriptor | THe descriptor for the property that is being defined or modified |
You can set the following properties on the descriptor object:
| Name | Description |
|---|---|
enumerable | If true, the property is iterated over in loops. Defaults to false. |
configurable | If false, the property cannot be deleted or changed. Defaults to false. |
writable | If false, the value of the property cannot be changed |
As shown in the code sample, when the configurable property is set to true,
the property can be modified.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); console.log(obj.site); // 👉️ google.com

When the configurable property is set to true, the property can also be
deleted.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); delete obj['site']; console.log(obj.site); // 👉️ undefined
In some cases, you might want to be able to modify the property but not to delete it.
When the writable property is set to true, the value of the property can be
changed.
By default, the property is set to false, just like the configurable
property.
The difference between the two properties is that setting writable to true
doesn't allow you to delete the property.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', writable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', writable: true, }); console.log(obj.site); // 👉️ google.com // ⛔️ TypeError: Cannot delete property 'site' of #<Object> delete obj['site'];
Notice that an error is raised when you attempt to delete a property with only
writable set to true.
This is not the case when configurable is set to true.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, }); delete obj['site']; console.log(obj.site); // 👉️ undefined
You can also set the enumerable property to true if you need to be able to
iterate over the property in loops.
const obj = Object.create({}); Object.defineProperty(obj, 'site', { value: 'bobbyhadz.com', configurable: true, enumerable: true, }); Object.defineProperty(obj, 'site', { value: 'google.com', configurable: true, enumerable: true, }); for (const key in obj) { console.log(key, obj[key]); // 👉️ site, google.com } console.log(obj.site); // 👉️ google.com
The enumerable property defaults to false.
You can learn more about the related topics by checking out the following tutorials: