petkaantonov/bluebird · error · TypeError

the promise constructor cannot be invoked directly See

Error message

the promise constructor cannot be invoked directly

    See http://goo.gl/MqrFmX

What it means

Bluebird's Promise constructor requires being called with `new` on the real Promise constructor with a function executor. The internal check(self, executor) throws TypeError(CONSTRUCT_ERROR_INVOCATION) when `this` is not a Bluebird Promise instance — i.e. the constructor was called without `new`, subclassed/invoked incorrectly, or the library's internal no-constructor sentinel (INTERNAL) misuse occurred.

Source

Thrown at src/promise.js:87

var PromiseArray =
    require("./promise_array")(Promise, INTERNAL,
                               tryConvertToPromise, apiRejection, Proxyable);
var Context = require("./context")(Promise);
 /*jshint unused:false*/
var createContext = Context.create;

var debug = require("./debuggability")(Promise, Context,
    enableAsyncHooks, disableAsyncHooks);
var CapturedTrace = debug.CapturedTrace;
var PassThroughHandlerContext =
    require("./finally")(Promise, tryConvertToPromise, NEXT_FILTER);
var catchFilter = require("./catch_filter")(NEXT_FILTER);
var nodebackForPromise = require("./nodeback");
var errorObj = util.errorObj;
var tryCatch = util.tryCatch;
function check(self, executor) {
    if (self == null || self.constructor !== Promise) {
        throw new TypeError(CONSTRUCT_ERROR_INVOCATION);
    }
    if (typeof executor !== "function") {
        throw new TypeError(FUNCTION_ERROR + util.classString(executor));
    }

}

function Promise(executor) {
    if (executor !== INTERNAL) {
        check(this, executor);
    }
    this._bitField = NO_STATE;
    this._fulfillmentHandler0 = undefined;
    this._rejectionHandler0 = undefined;
    this._promise0 = undefined;
    this._receiver0 = undefined;
    this._resolveFromExecutor(executor);
    this._promiseCreated();

View on GitHub (pinned to c220cfe480)

Solutions

  1. Always use `new`: new Promise((resolve, reject) => ...)
  2. Ensure there is exactly one bluebird version installed (dedupe with npm ls bluebird / npm dedupe)
  3. If subclassing, call super(executor) properly or use Promise.prototype methods instead of manual construction
  4. Check the import: the value you call `new` on must be bluebird's Promise, not a re-export that lost construct signature
  5. For Node >= 4, consider native Promise if subclassing semantics are causing conflicts

Example fix

// before
const p = Promise((resolve, reject) => resolve(1)); // missing new
// after
const p = new Promise((resolve, reject) => resolve(1));
Defensive patterns

Strategy: validation

Validate before calling

function safeNewPromise(executor) {
  if (typeof executor !== 'function') throw new TypeError('executor must be a function');
  return new Promise(executor); // note: new is required
}

Type guard

function isBluebirdPromise(Ctor) {
  try { const p = new Ctor(res => res(1)); return p instanceof Promise; }
  catch (e) { return false; }
}

Try / catch

let p;
try {
  p = new Promise((resolve, reject) => resolve(1));
} catch (e) {
  if (String(e.message).includes('cannot be invoked directly')) {
    throw new Error('Use `new Promise(...)` with bluebird\'s Promise; check for duplicate bluebird installs');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Promise(executor) without `new`; calling the constructor with .call/.apply on a wrong this; wrapping a subclass that doesn't properly forward to Bluebird's Promise; requiring multiple bluebird copies and cross-constructing with the wrong class.

Common situations: Migrating from native Promise code and dropping `new`; destructured import ({Promise}) misuse; TypeScript/Babel downleveling subclassed promises incorrectly; dual bluebird installations (one in node_modules of a dependency) causing instanceof-style mismatches.

Related errors


AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02). Data as JSON: /api/errors/d54ecbba4a47a56d. Report an issue: GitHub.