Skip to content

Bug: prefer-promise-reject-errors: false positives when Promise is shadowed #21000

Description

@navi2-dil

Environment

Node version: v24.15.0
npm version: 11.12.1
Local ESLint version: 10.4.1
Global ESLint version: none
Operating System: Windows 11

What parser are you using?

Default (Espree)

What did you do?

Configuration
export default [
    {
        rules: {
            "prefer-promise-reject-errors": "error",
        },
    },
];
// Promise is a parameter, not the global
function f(Promise) {
    return Promise.reject("oops");
}

// Promise is a local class, not the global
{
    class Promise { static reject(x) { return x; } }
    Promise.reject("oops");
}

What did you expect to happen?

No error. In both cases Promise is a local binding, not the global Promise, so the rule shouldn't assume .reject is Promise.reject.

What actually happened?

Both lines were reported with Expected the Promise rejection reason to be an Error.

Link to Minimal Reproducible Example

https://eslint.org/play/#eyJ0ZXh0IjoiZnVuY3Rpb24gZihQcm9taXNlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJvb3BzXCIpO1xuICB9XG5cbiAge1xuICAgICAgY2xhc3MgUHJvbWlzZSB7IHN0YXRpYyByZWplY3QoeCkgeyByZXR1cm4geDsgfSB9XG4gICAgICBQcm9taXNlLnJlamVjdChcIm9vcHNcIik7XG4gIH0iLCJvcHRpb25zIjp7InJ1bGVzIjp7InByZWZlci1wcm9taXNlLXJlamVjdC1lcnJvcnMiOlsiZXJyb3IiXX0sImxhbmd1YWdlT3B0aW9ucyI6eyJwYXJzZXJPcHRpb25zIjp7ImVjbWFGZWF0dXJlcyI6e319fX19

Participation

  • I am willing to submit a pull request for this issue.

AI acknowledgment

  • I did not use AI to generate this issue report.
  • (If the above is not checked) I have reviewed the AI-generated content before submitting.

Additional comments

The rule matches on the name Promise without ever checking it's the global one — so any local Promise (a param, a class, an import) trips it. Both paths have it: the Promise.reject() check uses isSpecificMemberAccess(..., "Promise", "reject"), and the new Promise() check just does callee.name === "Promise". Neither calls isGlobalReference.

no-async-promise-executor had the same problem and it was fixed in #20740 by checking isGlobalReference. no-promise-executor-return already does it too. Looks like this rule just got missed.

Metadata

Metadata

Assignees

Labels

acceptedThere is consensus among the team that this change meets the criteria for inclusionbugESLint is working incorrectlyrepro:yesIssues with a reproducible exampleruleRelates to ESLint's core rules

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Complete

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions