Automattic/mongoose · error · MongooseError
QueryCursor.prototype.close() no longer accepts a callback
Error message
QueryCursor.prototype.close() no longer accepts a callback
What it means
QueryCursor#close() became a promise-only async method in Mongoose 7 when callback support was removed. Passing a function as the first argument throws immediately, mirroring the same policy on AggregationCursor, so unmigrated call sites fail loudly.
Source
Thrown at lib/cursor/queryCursor.js:236
QueryCursor.prototype._markError = function(error) {
this._error = error;
return this;
};
/**
* Marks this cursor as closed. Will stop streaming and subsequent calls to
* `next()` will error.
*
* @return {Promise}
* @api public
* @method close
* @emits close
* @see AggregationCursor.close https://mongodb.github.io/node-mongodb-native/7.0/classes/AggregationCursor.html#close
*/
QueryCursor.prototype.close = async function close() {
if (typeof arguments[0] === 'function') {
throw new MongooseError('QueryCursor.prototype.close() no longer accepts a callback');
}
try {
await this.cursor.close();
this._closed = true;
this.emit('close');
} catch (error) {
this.listeners('error').length > 0 && this.emit('error', error);
throw error;
}
};
/**
* Marks this cursor as destroyed. Will stop streaming and subsequent calls to
* `next()` will error.
*
* @return {this}
* @api private
* @method _destroyView on GitHub (pinned to 49cdab0136)
Solutions
- Replace cursor.close(cb) with await cursor.close(), handling errors via try/catch
- Wrap for legacy callers: cursor.close().then(() => cb(null), cb)
- Grep the codebase for close( calls passing functions as part of the Mongoose 7 migration checklist
Example fix
// before
const cursor = Book.find().cursor();
cursor.close(function (err) {
if (err) console.error(err);
});
// after
const cursor = Book.find().cursor();
try {
await cursor.close();
} catch (err) {
console.error(err);
} Defensive patterns
Strategy: validation
Validate before calling
function closeCursor(cursor, ...args) {
if (args.some(a => typeof a === 'function')) {
throw new TypeError('close() takes no callback; await the returned promise');
}
return cursor.close();
} Prevention
- Use await cursor.close() exclusively in Mongoose 7+ code
- Shim legacy callers at the boundary: close().then(() => cb(null), cb)
- Include cursor utilities in upgrade checklists for major Mongoose versions
When it happens
Trigger: queryCursor.close(() => {}) or queryCursor.close(function (err) {...}) — any function as the first argument to close() on a cursor from Model.find().cursor().
Common situations: Upgrading Mongoose 6 to 7+ with legacy streaming code untouched; shared cursor utilities still written callback-style.
Related errors
- QueryCursor.prototype.next() no longer accepts a callback
- QueryCursor.prototype.eachAsync() no longer accepts a callba
- AggregationCursor.prototype.close() no longer accepts a call
- AggregationCursor.prototype.next() no longer accepts a callb
- AggregationCursor.prototype.eachAsync() no longer accepts a
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/2f3d565540fdd408.
Report an issue: GitHub.