{"record":{"id":"c102f32b4be3a108","repo":"Automattic/mongoose","slug":"model-createcollection-no-longer-accepts-a-callb","errorCode":null,"errorMessage":"Model.createCollection() no longer accepts a callback","messagePattern":"Model\\.createCollection\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":1224,"sourceCode":" *\n * #### Example:\n *\n *     const userSchema = new Schema({ name: String })\n *     const User = mongoose.model('User', userSchema);\n *\n *     User.createCollection().then(function(collection) {\n *       console.log('Collection is created!');\n *     });\n *\n * @api public\n * @param {object} [options] see [MongoDB driver docs](https://mongodb.github.io/node-mongodb-native/7.0/classes/Db.html#createCollection)\n * @returns {Promise}\n */\n\nModel.createCollection = async function createCollection(options) {\n  _checkContext(this, 'createCollection');\n  if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function') {\n    throw new MongooseError('Model.createCollection() no longer accepts a callback');\n  }\n\n  const preFilter = buildMiddlewareFilter(options, 'pre');\n  const postFilter = buildMiddlewareFilter(options, 'post');\n\n  // Remove middleware option before passing to MongoDB\n  if (options?.middleware != null) {\n    options = { ...options };\n    delete options.middleware;\n  }\n\n  [options] = await this.hooks.execPre('createCollection', this, [options], { filter: preFilter }).catch(err => {\n    if (err instanceof Kareem.skipWrappedFunction) {\n      return [err];\n    }\n    throw err;\n  });\n","sourceCodeStart":1206,"sourceCodeEnd":1242,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L1206-L1242","documentation":"Model.createCollection() explicitly creates the MongoDB collection (applying capped/timeseries/collation options) and is async-only; Mongoose 7 removed callbacks, so passing a function as either argument throws before any driver call is made. The returned promise resolves to the driver collection object.","triggerScenarios":"`User.createCollection(opts, cb)` or `User.createCollection(cb)`; code copied from Mongoose 5/6 docs where callbacks were the default style.","commonSituations":"Post-migration leftovers from mongoose < 7; setup scripts that used callbacks for collection bootstrapping.","solutions":["Await the call: `const collection = await User.createCollection(opts);`","Wrap setup in try/catch or .catch() for the error path (e.g. NamespaceExists)","Grep for `createCollection\\(` and ensure no trailing function argument remains"],"exampleFix":"// before\nUser.createCollection({ capped: true, size: 1024 }, (err) => { ... });\n\n// after\nawait User.createCollection({ capped: true, size: 1024 });","handlingStrategy":"validation","validationCode":"const isFn = (a) => typeof a === 'function';\nif (isFn(options)) throw new TypeError('createCollection() is promise-only');\nconst collection = await User.createCollection(options);","typeGuard":null,"tryCatchPattern":"try {\n  await User.createCollection(opts);\n} catch (err) {\n  if (err?.code === 48 /* NamespaceExists */) return; // idempotent bootstrap\n  throw err;\n}","preventionTips":["Write bootstrap code promise-first from the start; treat callback signatures as a compile error via TS types","Make collection bootstrap idempotent so re-runs don't depend on callback-style error plumbing"],"tags":["mongoose","callback-removed","promise","collection","migration"],"backgroundTag":"mongoose-callback-removed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}