Missing await on Async Call

ID

javascript.missing_await

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

async, error-handling, reliability

Description

Reports a call to an async function whose result is consumed (assigned, returned, used in an expression) but not preceded by await:

async function fetchUser() { return { id: 1 }; }

async function main() {
  const u = fetchUser();      // FLAW — u is a Promise, not the user object
  return u.id;                // ... and this trips: Promise has no `id`
}

Rationale

The value returned by an async function is always a Promise. Treating it as the resolved value introduces two failures: the caller computes on a Promise (which has no application-level fields), and the original errors carried by the Promise become unhandled rejections at the next tick.

The fix is almost always to add an await. When that’s not possible (for example, in a non-async caller that wants to forward the work), explicitly returning the Promise documents the intent.

Remediation

async function main() {
  const u = await fetchUser();
  return u.id;
}

// Or forward the Promise to a caller that awaits.
function asyncFactory() {
  return fetchUser();   // explicit return; consumer must await
}

Notes

The rule fires only when:

  • the called identifier resolves to a function declared async,

  • the call is in a value-consuming position (its parent is anything other than the surrounding ExpressionStatement),

  • no await appears between the call and the surrounding statement.

Bare expression statements (asyncFn();) are <em>not</em> reported here — they are covered by javascript.promise_result_ignored. Call results passed to .then()/.catch()/.finally() chains are also not reported because the chain explicitly handles the Promise.