{"record":{"id":"2772d7caf05fdb89","repo":"Automattic/mongoose","slug":"model-syncindexes-no-longer-accepts-a-callback","errorCode":null,"errorMessage":"Model.syncIndexes() no longer accepts a callback","messagePattern":"Model\\.syncIndexes\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":1332,"sourceCode":" * performance. Before running `syncIndexes()`, you can use the [`diffIndexes()` function](#Model.diffIndexes())\n * to check what indexes `syncIndexes()` will drop and create.\n *\n * #### Example:\n *\n *     const { toDrop, toCreate } = await Model.diffIndexes();\n *     toDrop; // Array of strings containing names of indexes that `syncIndexes()` will drop\n *     toCreate; // Array of strings containing names of indexes that `syncIndexes()` will create\n *\n * @param {object} [options] options to pass to `ensureIndexes()`\n * @param {boolean} [options.hideIndexes=false] set to `true` to hide indexes instead of dropping. Requires MongoDB server 4.4 or higher\n * @return {Promise}\n * @api public\n */\n\nModel.syncIndexes = async function syncIndexes(options) {\n  _checkContext(this, 'syncIndexes');\n  if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function') {\n    throw new MongooseError('Model.syncIndexes() no longer accepts a callback');\n  }\n\n  const autoCreate = options?.autoCreate ??\n    this.schema.options?.autoCreate ??\n    this.db.config.autoCreate ??\n    this.db.base?.options?.autoCreate ??\n    true;\n\n  if (autoCreate) {\n    try {\n      await this.createCollection();\n    } catch (err) {\n      if (err != null && (err.name !== 'MongoServerError' || err.code !== 48)) {\n        throw err;\n      }\n    }\n  }\n","sourceCodeStart":1314,"sourceCodeEnd":1350,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L1314-L1350","documentation":"Model.syncIndexes() reconciles the indexes defined in the schema with those in MongoDB (creating missing ones, dropping/hiding stale ones) and returns a promise of dropped index names. Since Mongoose 7 it accepts only an options object; a function in either positional slot throws immediately.","triggerScenarios":"`User.syncIndexes({ hideIndexes: true }, cb)` or `User.syncIndexes(cb)`; deployment scripts from the callback era that call syncIndexes per model in a loop with a callback.","commonSituations":"Mongoose 6-to-7 upgrades; index-sync utilities iterated with async.forEach-style callback helpers from older libraries.","solutions":["Await it: `const dropped = await User.syncIndexes();`","For many models: `await Promise.all(mongoose.modelNames().map(n => mongoose.model(n).syncIndexes()))`","Check `Model.diffIndexes()` first if you only want to preview changes without the misleading callback error"],"exampleFix":"// before\nUser.syncIndexes(function(err, dropped) { ... });\n\n// after\nconst dropped = await User.syncIndexes();","handlingStrategy":"validation","validationCode":"const isFn = (a) => typeof a === 'function';\nif (isFn(options) || isFn(arguments[1])) throw new TypeError('syncIndexes() is promise-only');\nconst dropped = await User.syncIndexes(options);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use TypeScript so callback overloads are absent and flagged at build time","Preview with `await Model.diffIndexes()` in CI instead of ad-hoc callback scripts"],"tags":["mongoose","callback-removed","promise","indexes","migration"],"backgroundTag":"mongoose-callback-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}