{"record":{"id":"137df9e01f5f0c0e","repo":"oxc-project/oxc","slug":"avoid-wrapping-return-values-in-promise-resolve","errorCode":null,"errorMessage":"Avoid wrapping return values in Promise.resolve","messagePattern":"Avoid wrapping return values in Promise\\.resolve","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/promise/no_return_wrap.rs","lineNumber":32,"sourceCode":"use oxc_ast_visit::VisitJs;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nfn no_return_wrap_diagnostic(span: Span, issue: &ReturnWrapper) -> OxcDiagnostic {\n    let warn_msg = match issue {\n        ReturnWrapper::Resolve => \"Avoid wrapping return values in Promise.resolve\",\n        ReturnWrapper::Reject => \"Expected throw instead of Promise.reject\",\n    };\n\n    let help_msg = match issue {\n        ReturnWrapper::Resolve => \"Return the value being passed into Promise.resolve instead\",\n        ReturnWrapper::Reject => \"Throw the value being passed into Promise.reject instead\",\n    };\n\n    OxcDiagnostic::warn(warn_msg).with_help(help_msg).with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoReturnWrap {\n    /// `allowReject` allows returning `Promise.reject` inside a promise handler.\n    ///\n    /// With `allowReject` set to `true` the following are examples of correct code:\n    ///\n    /// ```js\n    /// myPromise().then(\n    ///   function() {\n    ///     return Promise.reject(0)\n    /// })\n    /// ```\n    ///\n    /// ```js\n    /// myPromise().then().catch(() => Promise.reject(\"err\"))","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/promise/no_return_wrap.rs#L14-L50","documentation":"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.","triggerScenarios":"`promise.then(val => { return Promise.resolve(transform(val)) })`; returning `Promise.resolve(...)` from any `.then()`/`.catch()` handler.","commonSituations":"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.","solutions":["Return the value (or the thenable) directly: `return transform(val)`","If the value may be a promise, still return it directly - the chain flattens it","For conditionally-async work, return the promise from an async handler declared `async val => ...`"],"exampleFix":"// before\npromise.then(val => {\n  return Promise.resolve(transform(val))\n})\n\n// after\npromise.then(val => {\n  return transform(val)\n})","handlingStrategy":"validation","validationCode":"npx oxlint --promise/no-return-wrap src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember handlers auto-wrap: any returned value or thenable is assimilated","Grep for `return Promise.resolve(` inside `.then(`/`.catch(` callbacks during cleanup sprints","Reserve `Promise.resolve(...)` for starting chains or flattifying thenables, not for return values"],"tags":["promise","async","lint","code-style","oxlint"],"backgroundTag":"redundant-promise-resolve-wrapper","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}