Automattic/mongoose · error · MongooseError
Model.createCollection() no longer accepts a callback
Error message
Model.createCollection() no longer accepts a callback
What it means
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.
Source
Thrown at lib/model.js:1224
*
* #### Example:
*
* const userSchema = new Schema({ name: String })
* const User = mongoose.model('User', userSchema);
*
* User.createCollection().then(function(collection) {
* console.log('Collection is created!');
* });
*
* @api public
* @param {object} [options] see [MongoDB driver docs](https://mongodb.github.io/node-mongodb-native/7.0/classes/Db.html#createCollection)
* @returns {Promise}
*/
Model.createCollection = async function createCollection(options) {
_checkContext(this, 'createCollection');
if (typeof arguments[0] === 'function' || typeof arguments[1] === 'function') {
throw new MongooseError('Model.createCollection() no longer accepts a callback');
}
const preFilter = buildMiddlewareFilter(options, 'pre');
const postFilter = buildMiddlewareFilter(options, 'post');
// Remove middleware option before passing to MongoDB
if (options?.middleware != null) {
options = { ...options };
delete options.middleware;
}
[options] = await this.hooks.execPre('createCollection', this, [options], { filter: preFilter }).catch(err => {
if (err instanceof Kareem.skipWrappedFunction) {
return [err];
}
throw err;
});
View on GitHub (pinned to 49cdab0136)
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
Example fix
// before
User.createCollection({ capped: true, size: 1024 }, (err) => { ... });
// after
await User.createCollection({ capped: true, size: 1024 }); Defensive patterns
Strategy: validation
Validate before calling
const isFn = (a) => typeof a === 'function';
if (isFn(options)) throw new TypeError('createCollection() is promise-only');
const collection = await User.createCollection(options); Try / catch
try {
await User.createCollection(opts);
} catch (err) {
if (err?.code === 48 /* NamespaceExists */) return; // idempotent bootstrap
throw err;
} Prevention
- 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
When it happens
Trigger: `User.createCollection(opts, cb)` or `User.createCollection(cb)`; code copied from Mongoose 5/6 docs where callbacks were the default style.
Common situations: Post-migration leftovers from mongoose < 7; setup scripts that used callbacks for collection bootstrapping.
Related errors
- Model.init() no longer accepts a callback
- Model.syncIndexes() no longer accepts a callback
- Model.cleanIndexes() no longer accepts a callback
- Model.listIndexes() no longer accepts a callback
- Model.ensureIndexes() no longer accepts a callback
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/c102f32b4be3a108.
Report an issue: GitHub.