petkaantonov/bluebird · error · Error

cannot enable cancellation after promises are in use

Error message

cannot enable cancellation after promises are in use

What it means

Promise.config({cancellation: true}) must be enabled before any promise is created, because enabling cancellation swaps in new prototype methods (_onCancel, _propagateFrom, etc.). If async.haveItemsQueued() shows promises already in use, Bluebird throws this Error rather than retroactively changing prototype behavior on live promises.

Source

Thrown at src/debuggability.js:347

            Promise.longStackTraces();
        } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) {
            disableLongStackTraces();
        }
    }
    if ("warnings" in opts) {
        var warningsOption = opts.warnings;
        config.warnings = !!warningsOption;
        wForgottenReturn = config.warnings;

        if (util.isObject(warningsOption)) {
            if ("wForgottenReturn" in warningsOption) {
                wForgottenReturn = !!warningsOption.wForgottenReturn;
            }
        }
    }
    if ("cancellation" in opts && opts.cancellation && !config.cancellation) {
        if (async.haveItemsQueued()) {
            throw new Error(
                "cannot enable cancellation after promises are in use");
        }
        Promise.prototype._clearCancellationData =
            cancellationClearCancellationData;
        Promise.prototype._propagateFrom = cancellationPropagateFrom;
        Promise.prototype._onCancel = cancellationOnCancel;
        Promise.prototype._setOnCancel = cancellationSetOnCancel;
        Promise.prototype._attachCancellationCallback =
            cancellationAttachCancellationCallback;
        Promise.prototype._execute = cancellationExecute;
        propagateFromFunction = cancellationPropagateFrom;
        config.cancellation = true;
    }
    if ("monitoring" in opts) {
        if (opts.monitoring && !config.monitoring) {
            config.monitoring = true;
            Promise.prototype._fireEvent = activeFireEvent;
        } else if (!opts.monitoring && config.monitoring) {

View on GitHub (pinned to c220cfe480)

Solutions

  1. Enable cancellation at process startup, immediately after requiring bluebird and before any promise creation
  2. Reject the request cleanly instead of enabling cancellation dynamically; pre-configure at boot
  3. Set NODE_ENV=development or BLUEBIRD_DEBUG where cancellation can be enabled by default early
  4. Audit import order so config runs before modules that create promises
  5. Use AbortController/native facilities for late cancellation needs instead of toggling bluebird config

Example fix

// before
app.post('/job', (req, res) => {
  Promise.config({cancellation: true}); // too late
  ...
});
// after
// bootstrap.js (first file)
const Promise = require('bluebird');
Promise.config({cancellation: true});
// then routes can use promise.cancel()
Defensive patterns

Strategy: validation

Validate before calling

const Promise = require('bluebird');
Promise.config({ cancellation: true }); // first lines of bootstrap, before any promise creation

Type guard

function cancellationEnabledSafely(Promise) {
  try { Promise.config({ cancellation: true }); return true; }
  catch (e) { return e.message.indexOf('cancellation') === -1 ? (e => { throw e; })(e) : false; }
}

Try / catch

try {
  Promise.config({ cancellation: true });
} catch (e) {
  if (e.message.includes('cancellation after promises are in use')) {
    console.error('Enable cancellation at startup, before creating promises');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Promise.config({cancellation: true}) after at least one Bluebird promise has been instantiated — e.g. enabling it inside a request handler, a lazily-loaded module, or after another module already created promises at import time.

Common situations: Enabling cancellation mid-request to abort work; assuming config can be changed anytime; a dependency importing bluebird and creating promises before your config runs; copying example code into a controller instead of app bootstrap.

Related errors


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