{"record":{"id":"c6160f29baf87f98","repo":"Automattic/mongoose","slug":"model-bulkwrite-no-longer-accepts-a-callback","errorCode":null,"errorMessage":"Model.bulkWrite() no longer accepts a callback","messagePattern":"Model\\.bulkWrite\\(\\) no longer accepts a callback","errorType":"exception","errorClass":"MongooseError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":3426,"sourceCode":" * @param {number} [options.wtimeout=null] The [write concern timeout](https://www.mongodb.com/docs/manual/reference/write-concern/#wtimeout).\n * @param {boolean} [options.j=true] If false, disable [journal acknowledgement](https://www.mongodb.com/docs/manual/reference/write-concern/#j-option)\n * @param {boolean} [options.skipValidation=false] Set to true to skip Mongoose schema validation on bulk write operations. Mongoose currently runs validation on `insertOne` and `replaceOne` operations by default.\n * @param {boolean} [options.bypassDocumentValidation=false] If true, disable [MongoDB server-side schema validation](https://www.mongodb.com/docs/manual/core/schema-validation/) for all writes in this bulk.\n * @param {boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully. Note that Mongoose will still send all valid operations to the MongoDB server.\n * @param {boolean|\"throw\"} [options.strict=null] Overwrites the [`strict` option](https://mongoosejs.com/docs/guide.html#strict) on schema. If false, allows filtering and writing fields not defined in the schema for all writes in this bulk.\n * @param {boolean|object} [options.middleware=true] set to `false` to skip all user-defined middleware\n * @param {boolean} [options.middleware.pre=true] set to `false` to skip only pre hooks\n * @param {boolean} [options.middleware.post=true] set to `false` to skip only post hooks\n * @return {Promise} resolves to a [`BulkWriteOpResult`](https://mongodb.github.io/node-mongodb-native/7.0/classes/BulkWriteResult.html) if the operation succeeds\n * @api public\n */\n\nModel.bulkWrite = async function bulkWrite(ops, options) {\n  _checkContext(this, 'bulkWrite');\n\n  if (typeof options === 'function' ||\n      typeof arguments[2] === 'function') {\n    throw new MongooseError('Model.bulkWrite() no longer accepts a callback');\n  }\n\n  const ThisModel = this;\n  return traceBulkWrite(function maybeTracedBulkWrite() { return _bulkWrite.call(ThisModel, ops, options); }, () => ({\n    operation: 'bulkWrite',\n    collection: ThisModel.collection.name,\n    database: ThisModel.db?.name,\n    serverAddress: ThisModel.db?.host,\n    serverPort: ThisModel.db?.port,\n    args: { ops, options }\n  }));\n};\n\nasync function _bulkWrite(ops, options) {\n  options = options || {};\n  const preFilter = buildMiddlewareFilter(options, 'pre');\n  const postFilter = buildMiddlewareFilter(options, 'post');\n","sourceCodeStart":3408,"sourceCodeEnd":3444,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L3408-L3444","documentation":"Model.bulkWrite() is async and promise-only in Mongoose 7+; the guard throws (as a rejected promise) when options is a function or a third argument is a function, covering legacy bulkWrite(ops, callback) and bulkWrite(ops, options, callback) call forms.","triggerScenarios":"Model.bulkWrite(ops, cb) with the callback in the options slot, or Model.bulkWrite(ops, { ordered: false }, cb) with the callback third.","commonSituations":"Migrating bulk-migration scripts from Mongoose 6; wrapper utilities that append callbacks; copy-pasted legacy snippets performing bulk updates.","solutions":["Use await: const res = await Model.bulkWrite(ops, { ordered: false }); inside try/catch","Or .then()/.catch() on the returned promise","Include bulkWrite in the Mongoose 7 callback-migration sweep alongside create/insertMany/find* methods","Pin mongoose@6 temporarily if the rewrite must be deferred","Use TypeScript to catch removed overloads at compile time"],"exampleFix":"// before\nUser.bulkWrite(ops, (err, res) => { ... });\n\n// after\nconst res = await User.bulkWrite(ops);","handlingStrategy":"validation","validationCode":"function bulkWriteSafe(Model, ops, options) {\n  if (typeof options === 'function') throw new TypeError('bulkWrite: use await, not a callback');\n  return Model.bulkWrite(ops, options);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await Model.bulkWrite(ops, { ordered: false });\n} catch (err) {\n  if (/no longer accepts a callback/.test(err.message)) { /* migrate call site to await */ }\n  else throw err;\n}","preventionTips":["Migrate bulkWrite call sites with the same sweep as insertMany/create","TypeScript catches removed callback overloads","Keep bulk operation helpers promise-based and centralized"],"tags":["mongoose","callback","promise","migration","bulkwrite","bulk"],"backgroundTag":"callback-to-promise-migration","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}