{"record":{"id":"cc2fbcf30b309cc5","repo":"Automattic/mongoose","slug":"connection-prototype-destroy-no-longer-accepts-a","errorCode":null,"errorMessage":"Connection.prototype.destroy() no longer accepts a callback","messagePattern":"Connection\\.prototype\\.destroy\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/connection.js","lineNumber":1193,"sourceCode":"    err = new ServerSelectionError();\n    err.assimilateError(originalError);\n  }\n\n  return err;\n}\n\n/**\n * Destroy the connection. Similar to [`.close`](https://mongoosejs.com/docs/api/connection.html#Connection.prototype.close()),\n * but also removes the connection from Mongoose's `connections` list and prevents the\n * connection from ever being re-opened.\n *\n * @param {boolean} [force]\n * @returns {Promise}\n */\n\nConnection.prototype.destroy = async function destroy(force) {\n  if (typeof force === 'function' || (arguments.length === 2 && typeof arguments[1] === 'function')) {\n    throw new MongooseError('Connection.prototype.destroy() no longer accepts a callback');\n  }\n\n  if (force != null && typeof force === 'object') {\n    this.$wasForceClosed = !!force.force;\n  } else {\n    this.$wasForceClosed = !!force;\n  }\n\n  return this._close(force, true);\n};\n\n/**\n * Closes the connection\n *\n * @param {boolean} [force] optional\n * @return {Promise}\n * @api public\n */","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/connection.js#L1175-L1211","documentation":"destroy() permanently closes the connection — like close(), but it also removes the connection from mongoose's connections list and prevents reopening. Mongoose 7 removed callbacks, and any function argument (as force, or as a second argument after force) is rejected immediately. Note that an object as force (e.g. { force: true }) is still valid; only functions throw.","triggerScenarios":"conn.destroy(() => { ... }) or conn.destroy(true, (err) => { ... }).","commonSituations":"Graceful-shutdown handlers (SIGTERM/SIGINT) written callback-style in older codebases; migration to mongoose 7/8/9.","solutions":["Remove the callback and await: await conn.destroy()","In shutdown handlers: server.close(async () => { await conn.destroy(); })"],"exampleFix":"// before\nconn.destroy(true, (err) => { process.exit(0); });\n\n// after\nawait conn.destroy(true);\nprocess.exit(0);","handlingStrategy":"validation","validationCode":"function destroySafe(...args) {\n  if (args.some(a => typeof a === 'function')) {\n    throw new TypeError('destroy takes no callback — await the promise');\n  }\n  return conn.destroy(...args);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In shutdown handlers, await conn.destroy() inside the async handler","Remember destroy(force) also accepts { force: true } — objects are fine, functions are not","Test shutdown paths (SIGTERM) so migration breakage surfaces in CI, not production"],"tags":["destroy","connection-lifecycle","callbacks","migration","mongoose-7"],"backgroundTag":"callback-api-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}