How to resolve the Syntax error await is only valid in async function?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The error "await is only valid in async function" means JavaScript found an await in a place where the language grammar does not allow it. The fix is usually simple, but the correct solution depends on whether the code is inside a normal function, an event callback, or top-level module code.
Mark the function as async
The most common case is using await inside a function that was never marked async:
That fails because await suspends only async execution contexts. Add async to the function:
Now loadUser() returns a promise automatically, which means callers must either await it or handle the promise with .then().
Fix nested callbacks and array helpers
Another frequent trap is putting await inside a callback that is still synchronous, even if the outer function is async. For example:
The outer function is async, but the forEach callback is not. You have two clean fixes. The simplest is a normal loop:
If you want parallel requests, use Promise.all:
This pattern is important because many JavaScript bugs come from assuming await "inherits" async behavior from an outer scope. It does not. The exact function containing await must be async.
Use top-level await only in modules
Modern JavaScript allows top-level await, but only in ES modules. This is valid:
But it works only if the file runs as a module. In Node.js that usually means using an .mjs file or a package configured for ESM. In the browser, it means a module script:
If your environment is not a module, wrap the code in an async function instead:
If you cannot use async, fall back to promises
Some APIs expect a synchronous callback, or you may be working in older code where promise chains fit better. In those cases, replace await with .then():
This is not more modern, but it is still correct. The important part is matching the async style to the place where the code runs.
Common Pitfalls
The most common mistake is adding await inside forEach, filter, or other callbacks without marking those callbacks async or without reworking the flow. In many cases, a for...of loop is simpler and more correct.
Another pitfall is forgetting that async functions always return promises. After fixing the syntax error, the next bug is often a caller that expects a plain value.
Top-level await also causes confusion. It is valid only in module contexts, not in every JavaScript file by default.
Finally, make sure the thing you await is actually a promise or thenable. await on a non-promise value is legal, but it may hide a logic mistake where the asynchronous operation never existed in the first place.
Summary
- Put
awaitonly inside anasyncfunction or at top level in an ES module. - Check nested callbacks carefully because outer async functions do not make inner callbacks async.
- Prefer
for...oforPromise.alloverforEachwhen asynchronous work is involved. - Use top-level
awaitonly when your runtime treats the file as a module. - Fall back to promise chains when an async function is not the right tool for the surrounding API.

