Unsafe Continuation After Optional Chain
ID |
javascript.no_unsafe_optional_chaining |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
optional-chaining, reliability |
Description
Reports parenthesised optional-chain expressions whose undefined short-circuit value is then dereferenced or invoked. The classic shapes:
-
(a?.b).c— property access on a possibly-undefined value. -
(a?.b)["c"]— bracket-notation equivalent. -
(a?.b)()— call on a possibly-undefined function.
When the chain short-circuits to undefined, the next operation throws TypeError at runtime — the exact failure mode optional chaining was meant to prevent.
Rationale
// Bad — `(a?.b)` ends the chain at the parens; `.c` is not protected.
function read(a) {
return (a?.b).c;
}
// Bad — same hazard with bracket and call notation.
const x = (a?.b)["c"];
const y = (a?.b)();
Wrapping the optional chain in parentheses ends the chain there. Anything that follows operates on whatever the chain returned, including undefined.
Remediation
Continue the chain with another optional step (?., ?.(), ?.[ ]), or guard the value before using it:
// Good — chain continues; every step is optional.
function read(a) {
return a?.b?.c;
}
const x = a?.b?.["c"];
const y = a?.b?.();
// Good — explicit guard before the unsafe access.
if (a?.b) {
use(a.b.c);
}