Skip to main content

How to Resolve "TypeError: Cannot set property which has only a getter" Error in JavaScript

javascript-error-typeerror-cannot-set-property-which-has-only-a-getter

The TypeError: Cannot set property 'X' which has only a getter is a specific error that occurs when you try to assign a new value to a property that has been defined with a getter method but no corresponding setter method.

This guide will explain the role of getters and setters in creating "computed properties," show you why this error occurs, and teach you how to solve it by implementing a setter method.

The Core Concept: Getters and Setters (Computed Properties)

In JavaScript classes or objects, getters (get) and setters (set) allow you to define properties that are computed on the fly, rather than being stored directly.

  • A getter is a method that runs when you read a property. It's used to compute and return a value.
  • A setter is a method that runs when you assign a value to a property. It's used to update the underlying state.

Together, they create a property that looks normal from the outside but has custom logic behind it.

class MyClass {
get myProperty() {
// ... logic to compute a value ...
}
set myProperty(newValue) {
// ... logic to handle the new value ...
}
}

The Cause of the Error: A "Read-Only" Computed Property

The error occurs when you have defined a get for a property but have not defined a set. This effectively makes the property read-only. When you then try to assign a value to it, JavaScript has no setter to execute and throws the TypeError.

Problem: in this example, fullName is a computed property that is derived from firstName and lastName.

// Problem: The `fullName` property only has a getter.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}

const person = new Person('John', 'Doe');

console.log(person.fullName); // Output: "John Doe"

// ⛔️ TypeError: Cannot set property fullName of #<Person> which has only a getter
person.fullName = 'Jane Smith'; // Attempting to write to a read-only property
note

The code tries to assign a value to person.fullName, but there is no set fullName(...) method to handle this assignment.

The Solution: Define a Corresponding set Method

To make the computed property writable, you must define a set method with the same name. The setter will receive the value from the right side of the assignment as its argument.

// ✅ Solution: Add a setter for the `fullName` property.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

get fullName() {
return `${this.firstName} ${this.lastName}`;
}

// The `set` method receives the new value.
set fullName(newFullName) {
// We can parse the new value and update the underlying properties.
const [first, last] = newFullName.split(' ');
this.firstName = first;
this.lastName = last;
}
}

const person = new Person('John', 'Doe');
console.log(person.fullName); // Output: "John Doe"

// This now works! The setter is called with "Jane Smith".
person.fullName = 'Jane Smith';
console.log(person.fullName); // Output: "Jane Smith"
console.log(person.firstName); // Output: "Jane"

A Common Pitfall: Name Collisions in the Constructor

A more subtle version of this error can occur if a property name in your constructor collides with a getter name.

Example of problem:

class User {
// This getter is defined for the property 'name'.
get name() {
return this._name.toUpperCase();
}

constructor(name) {
// ⛔️ This line calls the `name` setter, but one doesn't exist!
this.name = name;

// It is trying to set a property that only has a getter.
}
}

const user = new User('Alice'); // TypeError
note

Why this fails: The assignment this.name = name in the constructor is an attempt to set the name property. Since a get name() exists, JavaScript looks for a corresponding set name(). When it doesn't find one, it throws the error.

Solution: use a different name for your internal, "private" property. A common convention is to prefix it with an underscore (_).

// ✅ Solution: Use an internal property like `_name`.
class User {
get name() {
return this._name.toUpperCase();
}

constructor(name) {
// This now assigns to `_name`, which is a regular property.
this._name = name;
}
}

const user = new User('Alice');
console.log(user.name); // Output: "ALICE"

Conclusion

The "Cannot set property which has only a getter" error is a feature of JavaScript's getter/setter mechanism.

  • It occurs when you try to assign a value to a property that has been defined with a get method but no corresponding set method.
  • The solution is to add a set method with the same name to handle the assignment and update the object's underlying state.
  • Be mindful of name collisions in your constructor. If you have a getter for prop, you cannot have a property named prop in your constructor; use an internal property like _prop instead.