sidorares/node-mysql2 · error · Error

You have tried to call .then(), .catch(), or invoked await o

Error message

You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require('mysql2/promise') instead of 'mysql2' for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at https://sidorares.github.io/node-mysql2/docs#using-promise-wrapper, or the mysql2 documentation at https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper

What it means

The Query command object (returned by the callback-style `connection.query()`) intentionally defines a `then()` method that throws, to fail loudly when a developer accidentally awaits it or treats it as a Promise. The callback API returns a Query/Readable stream, not a Promise; awaiting it is a programming error. The fix is to use the Promise wrapper via `require('mysql2/promise')` or `connection.promise().query()`.

Source

Thrown at lib/commands/query.js:44

    this.queryTimeout = null;
    this._fieldCount = 0;
    this._rowParser = null;
    this._fields = [];
    this._rows = [];
    this._receivedFieldsCount = 0;
    this._resultIndex = 0;
    this._localStream = null;
    this._unpipeStream = function () {};
    this._streamFactory = options.infileStreamFactory;
    this._connection = null;
  }

  then() {
    const err =
      "You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require('mysql2/promise') instead of 'mysql2' for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at https://sidorares.github.io/node-mysql2/docs#using-promise-wrapper, or the mysql2 documentation at https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper";

    console.log(err);
    throw new Error(err);
  }

  /* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
  start(_packet, connection) {
    if (connection.config.debug) {
      console.log('        Sending query command: %s', this.sql);
    }
    this._connection = connection;
    this.options = Object.assign({}, connection.config, this._queryOptions);
    this._setTimeout();

    const clientFlags =
      connection.config.clientFlags & (connection.serverCapabilityFlags || 0);
    const cmdPacket = new Packets.Query(
      this.sql,
      connection.config.charsetNumber,
      this._queryOptions.attributes,
      clientFlags

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Use the promise API: `const mysql = require('mysql2/promise'); const conn = await mysql.createConnection(...); await conn.query(sql)`.
  2. Or on an existing callback connection/pool: `await conn.promise().query(sql)`.
  3. Do not await or call `.then()` on the return value of callback-style `.query()`.

Example fix

// before
const mysql = require('mysql2');
const conn = mysql.createConnection({ host, user, password });
const rows = await conn.query('SELECT 1'); // throws

// after
const mysql = require('mysql2/promise');
const conn = await mysql.createConnection({ host, user, password });
const [rows] = await conn.query('SELECT 1');
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure you imported the promise API before awaiting
const isPromiseApi = typeof conn.promise === 'function' && conn.__isPromiseWrapped;
if (!isPromiseApi && typeof conn.query === 'function') {
  // use conn.promise().query() instead of awaiting conn.query()
}

Type guard

function isPromiseQueryResult(obj) {
  return obj != null && typeof obj.then === 'function';
}
// But better: just require('mysql2/promise') so the guard is unnecessary.

Prevention

When it happens

Trigger: Doing `await conn.query(sql)` where `conn` came from `require('mysql2')` (callback API). Or `conn.query(sql).then(...)`. The presence of a `then` method makes JS think the object is a thenable, so `await` invokes it and triggers the throw.

Common situations: Migrating from callback-style to async/await without switching to `mysql2/promise`; copy-pasting promise-style code onto a callback connection; mixing `mysql` (callback) and `mysql2/promise` in the same file.

Related errors


AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03). Data as JSON: /data/errors/9563707f9a26077b.json. Report an issue: GitHub.