Redundant await

ID

javascript.redundant_await

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

performance, reliability

Description

Reports await applied where it cannot meaningfully suspend execution. Two cases are flagged:

  • await await expr — the inner await already resolves the value to its non-thenable form; the outer await adds an extra microtask hop and nothing else.

  • await <literal> where the literal is a primitive (number, string, boolean, null, regex), array literal, object literal, or template literal. Awaiting a non-thenable simply schedules a microtask before continuing — pure overhead and noise.

The rule does not flag await x when x could be a promise (any non-literal expression). A real promise type cannot be inferred without flow / type analysis.

Rationale

  • await await x is almost always a typo or a leftover from a refactor (the first await was added then forgotten when wrapping happened later). It pays a microtask round-trip every call.

  • await 1 works — the engine wraps the value with Promise.resolve — but it costs a microtask and the reader has to stop and ask "is 1 actually a promise here?". Using the literal directly is clearer.

// Bad
const u = await await fetchUser();
const x = await 1;
const tpl = await `${name}-${id}`;

Remediation

Drop the redundant await:

// Good
const u = await fetchUser();
const x = 1;
const tpl = `${name}-${id}`;

References