sidorares/node-mysql2 · error · Error

no Promise implementation available.Use promise-enabled…

Error message

no Promise implementation available.Use promise-enabled node version or pass userland Promise implementation as parameter, for example: { Promise: require('bluebird') }

What it means

Thrown by createConnection (from 'mysql2/promise') after computing thePromise = opts.Promise || Promise. It fires only when that resolves to a falsy value, i.e. no native global Promise AND no opts.Promise supplied. Native Promise has shipped since Node 0.12, so on any supported runtime (Node 14+) this is effectively dead code — it triggers only if the global Promise has been deleted/overwritten with a falsy value or a polyfill-less exotic runtime is used. The error message is a legacy artifact from the bluebird era.

Solutions

  1. Run on Node 14+ (the driver's minimum) — global Promise is always present and this branch is unreachable.
  2. Pass a Promise implementation explicitly: createConnection({ Promise: require('bluebird'), ... }) or { Promise: globalThis.Promise }.
  3. Ensure no code deletes or shadows the global Promise before mysql2 is required.

Example fix

// before (exotic/polyfill-less runtime)
const conn = await createConnection({ host: 'localhost' });
// after
const conn = await createConnection({ host: 'localhost', Promise: require('bluebird') });
Defensive patterns

Strategy: validation

Validate before calling

function ensurePromise(opts) {
  const P = (opts && opts.Promise) || globalThis.Promise;
  if (typeof P !== 'function') {
    throw new Error('No Promise implementation available; pass { Promise: require("bluebird") } or use Node 14+');
  }
  return opts;
}

const conn = await createConnection(ensurePromise(rawOpts));

Type guard

function hasUsablePromise(opts) {
  const P = (opts && opts.Promise) || globalThis.Promise;
  return typeof P === 'function' && typeof P.resolve === 'function';
}

Prevention

When it happens

Trigger: Running on a JS runtime without a native Promise global and not passing opts.Promise; or test/sandbox code that deletes globalThis.Promise before requiring mysql2/promise; or explicitly passing { Promise: null } in such an environment.

Common situations: Edge embeded JS engines lacking Promise; security sandboxes that strip globals; legacy Node 0.10/0.12 deployments (unsupported by this driver's Node 14 minimum); mistaken polyfill configuration that sets opts.Promise to a non-constructor.

Related errors


AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11). Data as JSON: /api/errors/57fb8aa4f99e06de. Report an issue: GitHub.

Appendix: source

Thrown at promise.js:26

const createPool = require('./lib/create_pool.js');
const createPoolCluster = require('./lib/create_pool_cluster.js');
const PromiseConnection = require('./lib/promise/connection.js');
const PromisePool = require('./lib/promise/pool.js');
const {
  captureStackHolder,
  applyCapturedStack,
} = require('./lib/promise/capture_local_err.js');
const makeDoneCb = require('./lib/promise/make_done_cb.js');
const PromisePoolConnection = require('./lib/promise/pool_connection.js');
const inheritEvents = require('./lib/promise/inherit_events.js');
const PromisePoolNamespace = require('./lib/promise/pool_cluster');

function createConnectionPromise(opts) {
  const coreConnection = createConnection(opts);
  const stackHolder = captureStackHolder(createConnectionPromise);
  const thePromise = opts.Promise || Promise;
  if (!thePromise) {
    throw new Error(
      'no Promise implementation available.' +
        'Use promise-enabled node version or pass userland Promise' +
        " implementation as parameter, for example: { Promise: require('bluebird') }"
    );
  }
  return new thePromise((resolve, reject) => {
    coreConnection.once('connect', () => {
      resolve(new PromiseConnection(coreConnection, thePromise));
    });
    coreConnection.once('error', (err) => {
      applyCapturedStack(err, stackHolder);
      reject(err);
    });
  });
}

// note: the callback of "changeUser" is not called on success
// hence there is no possibility to call "resolve"

View on GitHub (pinned to 8b1f829d37)