oxc-project/oxc · warning · OxcDiagnostic

Avoid nesting promises.

Error message

Avoid nesting promises.

What it means

Diagnostic from the oxlint rule `promise/no-nesting` (plugin `promise`). It flags calls to `.then()` or `.catch()` (any member call the rule's `is_promise` utility recognizes as promise-returning) made inside the callback of another `.then()`/`.catch()`, tracked via scope IDs of enclosing function scopes. Nested chains defeat the flat composability promises are designed for: each nested level needs its own error handling and the outer chain does not wait for the inner one.

Solutions

  1. Return the inner promise from the handler so the outer chain waits on it and errors flow to one `catch`
  2. Rewrite the sequence with `async`/`await` inside a `try`/`catch`
  3. For parallel inner work, return `Promise.all(items.map(...))` from the handler
  4. If nesting is deliberate (rare), disable the rule inline with an oxlint suppression comment

Example fix

// before
api.users().then(users => {
  api.posts(users[0].id).then(posts => {
    console.log(posts)
  })
})

// after
api.users()
  .then(users => api.posts(users[0].id))
  .then(posts => console.log(posts))
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --promise/no-nesting src/

Prevention

When it happens

Trigger: Invoking `promise.then(...)` or `promise.catch(...)` inside another `.then(fn)` callback body; wrapping per-item async work for an array inside a then handler without returning it.

Common situations: Migrating callback-style code to promises step by step; sequential dependent requests written inline; forgetting that returning the inner promise flattens the chain.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/488de55c3e909fc9. Report an issue: GitHub.

Appendix: source

Thrown at crates/oxc_linter/src/rules/promise/no_nesting.rs:13

use oxc_ast::{
    AstKind,
    ast::{CallExpression, Expression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::ScopeId;
use oxc_span::{GetSpan, Span};

use crate::{AstNode, context::LintContext, rule::Rule, utils::is_promise};

fn no_nesting_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Avoid nesting promises.")
        .with_help("Refactor so that promises are chained in a flat manner.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NoNesting;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow nested `then()` or `catch()` statements.
    ///
    /// ### Why is this bad?
    ///
    /// Nesting promises makes code harder to read and understand.
    ///
    /// ### Examples
    ///

View on GitHub (pinned to e1e7af627c)