Redundant await

ID

javascript.redundant_await

Severity

low

Remediation Complexity

auto_fix

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