oxc-project/oxc · warning · OxcDiagnostic
Unexpected `await` inside a loop.
Error message
Unexpected `await` inside a loop.
What it means
Diagnostic from the oxlint rule `no-await-in-loop` (crates/oxc_linter/src/rules/eslint/no_await_in_loop.rs). It reports an `await` expression appearing in the body of a `for`, `for-in`, `for-of`, `while`, or `do-while` loop. Awaiting inside a loop serializes iterations, so total time is the sum of all awaited operations instead of running them concurrently; the rule's help text suggests collecting the promises and using `Promise.all()`.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_await_in_loop.rs:12
use oxc_ast::{
AstKind,
ast::{Expression, Statement, VariableDeclarationKind},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};
fn no_await_in_loop_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected `await` inside a loop.")
.with_help("Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoAwaitInLoop;
declare_oxc_lint!(
/// ### What it does
///
/// This rule disallows the use of `await` within loop bodies. (for, for-in, for-of, while, do-while).
///
/// ### Why is this bad?
///
/// It potentially indicates that the async operations are not being effectively parallelized.
/// Instead, they are being run in series, which can lead to poorer performance.
///
/// ### ExamplesView on GitHub (pinned to e1e7af627c)
Solutions
- If iterations are independent, map to promises and run concurrently: `await Promise.all(ids.map(id => save(id)));`.
- For bounded concurrency, use a worker-pool pattern (e.g. process chunks with `Promise.all` over slices) or p-limit style batching.
- If each iteration genuinely depends on the previous result (sequential requirement is intentional), suppress with `// oxlint-disable-next-line no-await-in-loop` on that line.
- Disable the rule per-directory in .oxlintrc.json if the codebase intentionally uses sequential awaits as a pattern (e.g. rate-limit compliance).
Example fix
// before
for (const url of urls) {
const res = await fetch(url);
results.push(res);
}
// after
const results = await Promise.all(urls.map(url => fetch(url))); Defensive patterns
Strategy: fallback
Validate before calling
// Before committing, detect awaits directly inside loop bodies in changed files
const loopAwait = /(?:for\s*\(|while\s*\(|do\s*\{)/[Symbol.replace];
// simplest reliable gate: run oxlint on the diff and treat no-await-in-loop as blocking
execSync('oxlint --deny-warnings .'); Prevention
- Default to Promise.all/map when iterating over independent async work.
- Add `// oxlint-disable-next-line no-await-in-loop` only with a comment stating the sequential dependency.
- Use a concurrency limiter for rate-limited APIs instead of sequential awaits.
When it happens
Trigger: Any AwaitExpression nested inside the body (Statement list) of a ForStatement, ForInStatement, ForOfStatement, WhileStatement, or DoWhileStatement — e.g. `for (const id of ids) { await save(id); }`.
Common situations: Batch-processing API requests, saving database rows, or fetching per-key lookups in a loop; code written for correctness first and never parallelized; adopting oxlint's default `restriction`/eslint rule set on existing server code.
Related errors
- Promise executor functions should not be `async`.
- Avoid nesting promises.
- Do not use `new` on `Promise.{static_name}`
- Avoid using promises inside of callbacks.
- Don't return in a finally callback
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/79d21d1e05c210ef.
Report an issue: GitHub.