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
awaitappears 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.