oxc-project/oxc · warning · OxcDiagnostic

Avoid wrapping return values in Promise.resolve

Error message

Avoid wrapping return values in Promise.resolve

What it means

Diagnostic from the oxlint rule `promise/no-return-wrap` (plugin `promise`) for the Resolve variant. It flags `return Promise.resolve(x)` inside a promise handler (then/catch callback). Returning a value from a handler already wraps it: the chain assimilates thenables automatically, so the explicit `Promise.resolve` wrapper adds an extra microtask tick and visual noise for no behavior change. The rule has an `allowReject` option, but it only affects the reject variant, not this one.

Source

Thrown at crates/oxc_linter/src/rules/promise/no_return_wrap.rs:32

use oxc_ast_visit::VisitJs;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use schemars::JsonSchema;
use serde::Deserialize;

fn no_return_wrap_diagnostic(span: Span, issue: &ReturnWrapper) -> OxcDiagnostic {
    let warn_msg = match issue {
        ReturnWrapper::Resolve => "Avoid wrapping return values in Promise.resolve",
        ReturnWrapper::Reject => "Expected throw instead of Promise.reject",
    };

    let help_msg = match issue {
        ReturnWrapper::Resolve => "Return the value being passed into Promise.resolve instead",
        ReturnWrapper::Reject => "Throw the value being passed into Promise.reject instead",
    };

    OxcDiagnostic::warn(warn_msg).with_help(help_msg).with_label(span)
}

#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoReturnWrap {
    /// `allowReject` allows returning `Promise.reject` inside a promise handler.
    ///
    /// With `allowReject` set to `true` the following are examples of correct code:
    ///
    /// ```js
    /// myPromise().then(
    ///   function() {
    ///     return Promise.reject(0)
    /// })
    /// ```
    ///
    /// ```js
    /// myPromise().then().catch(() => Promise.reject("err"))

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Return the value (or the thenable) directly: `return transform(val)`
  2. If the value may be a promise, still return it directly - the chain flattens it
  3. For conditionally-async work, return the promise from an async handler declared `async val => ...`

Example fix

// before
promise.then(val => {
  return Promise.resolve(transform(val))
})

// after
promise.then(val => {
  return transform(val)
})
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --promise/no-return-wrap src/

Prevention

When it happens

Trigger: `promise.then(val => { return Promise.resolve(transform(val)) })`; returning `Promise.resolve(...)` from any `.then()`/`.catch()` handler.

Common situations: Authors unsure whether handlers auto-wrap return values; refactors out of `new Promise` wrappers that leave `Promise.resolve` behind; defensive wrapping of possibly-thenable values.

Related errors


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