Back to blog
AsyncASYNC0012026-02-044 min

Forgot Await: The Most Common Async Bug

In Python and JavaScript, calling an async function without await doesn't raise an error. The function returns a Promise (or coroutine) that silently goes unresolved. The operation you expected to happen — the database write, the API call, the file save — never executes.

Why this is so common

When AI generates code, it often converts synchronous functions to async as part of a larger refactor. It adds async to the function definition and updates most call sites. But "most" isn't "all." One missing await buried in an error handler or a cleanup function goes unnoticed because the happy path still works.

In JavaScript, the problem is worse: calling an async function without await returns a Promise object that is truthy. So if (saveToDatabase(data)) evaluates to true even though nothing was saved.

Real-world impact

We've seen this cause:

- Audit logs that silently stop recording - Payment webhooks that acknowledge but never process - Background jobs that appear to complete but skip critical steps - Error reporters that fail to report their own errors

The pattern is always the same: the system looks healthy because the async call doesn't throw — it just doesn't do anything.

What ASYNC001 catches

ASYNC001 identifies every call to an async function that isn't preceded by await, yield from, or otherwise consumed. It works across Python and JavaScript/TypeScript, understands method chains, and handles the common patterns where a missing await causes silent failures.

This is one of our most frequently triggered checks — and one where developers almost always say "oh, that would have been bad."

ASYNC001 is available with a StableStack license.

pip install stablestack