SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions

The JavaScript exception "cannot use ?? unparenthesized within || and && expressions" occurs when an nullish coalescing operator is used with a logical OR or logical AND in the same expression without parentheses.

Message

SyntaxError: Unexpected token '??' (V8-based)
SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions (Firefox)
SyntaxError: Unexpected token '??'. Coalescing and logical operators used together in the same expression; parentheses must be used to disambiguate. (Safari)

Error type

What went wrong?

The operator precedence chain looks like this:

|   >   &&   >   ||   >   =
|   >   ??   >   =

However, the precedence between ?? and &&/|| is intentionally undefined, because the short circuiting behavior of logical operators can make the expression's evaluation counter-intuitive. Therefore, the following combinations are all syntax errors, because the language doesn't know how to parenthesize the operands:

js
a ?? b || c;
a || b ?? c;
a ?? b && c;
a && b ?? c;

Instead, make your intent clear by parenthesizing either side explicitly:

js
(a ?? b) || c;
a ?? (b && c);

Examples

When migrating legacy code that uses || and && for guarding against null or undefined, you may often convert it partially:

js
function getId(user, fallback) {
  // Previously: user && user.id || fallback
  return user && user.id ?? fallback; // SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions
}

Instead, consider parenthesizing the &&:

js
function getId(user, fallback) {
  return (user && user.id) ?? fallback;
}

Even better, consider using optional chaining instead of &&:

js
function getId(user, fallback) {
  return user?.id ?? fallback;
}

See also