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,
clientFlagsView on GitHub (pinned to 5ebe8903d6)
Solutions
- Use the promise API: `const mysql = require('mysql2/promise'); const conn = await mysql.createConnection(...); await conn.query(sql)`.
- Or on an existing callback connection/pool: `await conn.promise().query(sql)`.
- 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
- Consistently use `require('mysql2/promise')` in async codebases.
- Never import the callback API in files that use await on queries.
- Lint against `await` on the return of callback-API `.query()`/`.execute()`.
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
- Bind parameters must be array if namedPlaceholders parameter
- Bind parameters must not contain undefined. To pass SQL NULL
- Bind parameters must not contain function(s). To pass the bo
- Callback function is not available with promise clients.
- Callback function is not available with promise clients.
AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03).
Data as JSON: /data/errors/9563707f9a26077b.json.
Report an issue: GitHub.