SyntaxError: invalid assignment left-hand side

The JavaScript exception "invalid assignment left-hand side" occurs when there was an unexpected assignment somewhere. It may be triggered when a single = sign was used instead of == or ===.

Message

SyntaxError: Invalid left-hand side in assignment (V8-based)
SyntaxError: invalid assignment left-hand side (Firefox)
SyntaxError: Left side of assignment is not a reference. (Safari)

ReferenceError: Invalid left-hand side in assignment (V8-based)
ReferenceError: cannot assign to function call (Firefox)
ReferenceError: Left side of assignment is not a reference. (Safari)

Error type

SyntaxError or ReferenceError, depending on the syntax.

What went wrong?

There was an unexpected assignment somewhere. This might be due to a mismatch of an assignment operator and an equality operator, for example. While a single = sign assigns a value to a variable, the == or === operators compare a value.

Examples

Typical invalid assignments

js
if (Math.PI + 1 = 3 || Math.PI + 1 = 4) {
  console.log("no way!");
}
// SyntaxError: invalid assignment left-hand side

const str = "Hello, "
+= "is it me "
+= "you're looking for?";
// SyntaxError: invalid assignment left-hand side

In the if statement, you want to use an equality operator (===), and for the string concatenation, the plus (+) operator is needed.

js
if (Math.PI + 1 === 3 || Math.PI + 1 === 4) {
  console.log("no way!");
}

const str = "Hello, "
  + "from the "
  + "other side!";

Assignments producing ReferenceErrors

Invalid assignments don't always produce syntax errors. Sometimes the syntax is almost correct, but at runtime, the left hand side expression evaluates to a value instead of a reference, so the assignment is still invalid. Such errors occur later in execution, when the statement is actually executed.

js
function foo() {
  return { a: 1 };
}
foo() = 1; // ReferenceError: invalid assignment left-hand side

Function calls, new calls, super(), and this are all values instead of references. If you want to use them on the left hand side, the assignment target needs to be a property of their produced values instead.

js
function foo() {
  return { a: 1 };
}
foo().a = 1;

Note: In Firefox and Safari, the first example produces a ReferenceError in non-strict mode, and a SyntaxError in strict mode. Chrome throws a runtime ReferenceError for both strict and non-strict modes.

Using optional chaining as assignment target

Optional chaining is not a valid target of assignment.

js
obj?.foo = 1; // SyntaxError: invalid assignment left-hand side

Instead, you have to first guard the nullish case.

js
if (obj) {
  obj.foo = 1;
}

See also