{"id":"9563707f9a26077b","repo":"sidorares/node-mysql2","slug":"you-have-tried-to-call-then-catch-or-invok","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/commands/query.js","lineNumber":44,"sourceCode":"    this.queryTimeout = null;\n    this._fieldCount = 0;\n    this._rowParser = null;\n    this._fields = [];\n    this._rows = [];\n    this._receivedFieldsCount = 0;\n    this._resultIndex = 0;\n    this._localStream = null;\n    this._unpipeStream = function () {};\n    this._streamFactory = options.infileStreamFactory;\n    this._connection = null;\n  }\n\n  then() {\n    const err =\n      \"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\";\n\n    console.log(err);\n    throw new Error(err);\n  }\n\n  /* eslint no-unused-vars: [\"error\", { \"argsIgnorePattern\": \"^_\" }] */\n  start(_packet, connection) {\n    if (connection.config.debug) {\n      console.log('        Sending query command: %s', this.sql);\n    }\n    this._connection = connection;\n    this.options = Object.assign({}, connection.config, this._queryOptions);\n    this._setTimeout();\n\n    const clientFlags =\n      connection.config.clientFlags & (connection.serverCapabilityFlags || 0);\n    const cmdPacket = new Packets.Query(\n      this.sql,\n      connection.config.charsetNumber,\n      this._queryOptions.attributes,\n      clientFlags","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/5ebe8903d6aea2d8ea1490e11b52491526e50f19/lib/commands/query.js#L26-L62","documentation":"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()`.","triggerScenarios":"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.","commonSituations":"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.","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()`."],"exampleFix":"// before\nconst mysql = require('mysql2');\nconst conn = mysql.createConnection({ host, user, password });\nconst rows = await conn.query('SELECT 1'); // throws\n\n// after\nconst mysql = require('mysql2/promise');\nconst conn = await mysql.createConnection({ host, user, password });\nconst [rows] = await conn.query('SELECT 1');","handlingStrategy":"type-guard","validationCode":"// Ensure you imported the promise API before awaiting\nconst isPromiseApi = typeof conn.promise === 'function' && conn.__isPromiseWrapped;\nif (!isPromiseApi && typeof conn.query === 'function') {\n  // use conn.promise().query() instead of awaiting conn.query()\n}","typeGuard":"function isPromiseQueryResult(obj) {\n  return obj != null && typeof obj.then === 'function';\n}\n// But better: just require('mysql2/promise') so the guard is unnecessary.","tryCatchPattern":null,"preventionTips":["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()`."],"tags":["promise","query","api-misuse"],"analyzedSha":"5ebe8903d6aea2d8ea1490e11b52491526e50f19","analyzedAt":"2026-08-03T18:58:53.602Z","schemaVersion":2}