oxc-project/oxc · warning · OxcDiagnostic

Promise constructor parameters must be named to match `{patt

Error message

Promise constructor parameters must be named to match `{pattern}`

What it means

Diagnostic from the oxlint rule `promise/param-names` (plugin `promise`, category `style`). The Promise constructor uses the Revealing Constructor pattern: `new Promise(executor)` passes `(resolve, reject)` positionally. This rule enforces conventional names so readers never have to check the order: by default the first parameter must match `^_?resolve$` and the second `^_?reject$`; the `resolvePattern`/`rejectPattern` config options (regex strings) replace those defaults. It only checks `new Promise(...)` calls with exactly one argument that is a function or arrow expression, and only plain `BindingIdentifier` parameters.

Source

Thrown at crates/oxc_linter/src/rules/promise/param_names.rs:21

use serde::Deserialize;

use oxc_ast::{
    AstKind,
    ast::{BindingPattern, Expression, FormalParameter, FormalParameters},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

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

fn param_names_diagnostic(span: Span, pattern: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "Promise constructor parameters must be named to match `{pattern}`"
    ))
    .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct ParamNames(Box<ParamNamesConfig>);

#[derive(Debug, Default, Clone, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase", default)]
pub struct ParamNamesConfig {
    /// Regex pattern used to validate the `resolve` parameter name. If provided, this pattern
    /// is used instead of the default `^_?resolve$` check.
    #[serde(default, deserialize_with = "deserialize_regex_option")]
    resolve_pattern: Option<Regex>,
    /// Regex pattern used to validate the `reject` parameter name. If provided, this pattern
    /// is used instead of the default `^_?reject$` check.
    #[serde(default, deserialize_with = "deserialize_regex_option")]

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Rename the executor parameters to `resolve` and `reject` (an optional leading underscore for unused ones is allowed)
  2. If custom names are a team convention, configure them: `{ "resolvePattern": "^yes$", "rejectPattern": "^no$" }`
  3. For promisifying libraries, prefer `util.promisify` so no executor is written at all

Example fix

// before
new Promise((ok, fail) => {
  doWork().then(ok, fail)
})

// after
new Promise((resolve, reject) => {
  doWork().then(resolve, reject)
})
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --promise/param-names src/

Prevention

When it happens

Trigger: `new Promise(function (reject, resolve) {})` (swapped order); `new Promise((ok, fail) => {})` (non-standard names); `new Promise(yes => {})`; or standard names that fail a custom configured pattern.

Common situations: Teams porting eslint-plugin-promise configs to oxlint; code that deliberately uses domain-specific names and needs the pattern options; accidental parameter swaps that still 'work' but read dangerously.

Related errors


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