{"record":{"id":"5a6d951a644e7d7e","repo":"mongodb/node-mongodb-native","slug":"invalid-bulkoperation-batch-cannot-be-empty","errorCode":null,"errorMessage":"Invalid BulkOperation, Batch cannot be empty","messagePattern":"Invalid BulkOperation, Batch cannot be empty","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/bulk/common.ts","lineNumber":1201,"sourceCode":"      throw new MongoBatchReExecutionError();\n    }\n\n    const writeConcern = WriteConcern.fromOptions(options);\n    if (writeConcern) {\n      this.s.writeConcern = writeConcern;\n    }\n\n    // If we have current batch\n    if (this.isOrdered) {\n      if (this.s.currentBatch) this.s.batches.push(this.s.currentBatch);\n    } else {\n      if (this.s.currentInsertBatch) this.s.batches.push(this.s.currentInsertBatch);\n      if (this.s.currentUpdateBatch) this.s.batches.push(this.s.currentUpdateBatch);\n      if (this.s.currentRemoveBatch) this.s.batches.push(this.s.currentRemoveBatch);\n    }\n    // If we have no operations in the bulk raise an error\n    if (this.s.batches.length === 0) {\n      throw new MongoInvalidArgumentError('Invalid BulkOperation, Batch cannot be empty');\n    }\n\n    this.s.executed = true;\n    const finalOptions = resolveOptions(this.collection, { ...this.s.options, ...options });\n\n    // if there is no timeoutContext provided, create a timeoutContext and use it for\n    // all batches in the bulk operation\n    finalOptions.timeoutContext ??= TimeoutContext.create({\n      session: finalOptions.session,\n      timeoutMS: finalOptions.timeoutMS,\n      serverSelectionTimeoutMS: this.collection.client.s.options.serverSelectionTimeoutMS,\n      waitQueueTimeoutMS: this.collection.client.s.options.waitQueueTimeoutMS\n    });\n\n    if (finalOptions.session == null) {\n      // if there is not an explicit session provided to `execute()`, create\n      // an implicit session and use that for all batches in the bulk operation\n      return await this.collection.client.withSession({ explicit: false }, async session => {","sourceCodeStart":1183,"sourceCodeEnd":1219,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/bulk/common.ts#L1183-L1219","documentation":"Thrown as MongoInvalidArgumentError by BulkOperationBase.execute() (src/bulk/common.ts:1201) when execute() is called on a bulk operation to which no operations were added. The driver has no batch to send, so it refuses to issue an empty wire command rather than round-tripping a no-op.","triggerScenarios":"Calling `await coll.initializeOrderedBulkOp().execute()` (or the unordered variant) without any preceding insert/find/update/delete calls. Guarded by `if (this.s.batches.length === 0)` at src/bulk/common.ts:1200.","commonSituations":"A loop that builds ops conditionally produced zero ops, a code path that skips all operations due to empty input, or calling execute() defensively at the end of a function without checking that ops were added.","solutions":["Guard the execute() call: only call it when you have at least one operation (`if (myOps.length) await coll.bulkWrite(myOps)`).","Skip the whole bulk block when the input list is empty.","If using the builder API, track whether you added any ops before invoking execute()."],"exampleFix":"// before\nconst bulk = coll.initializeUnorderedBulkOp();\nfor (const id of []) { // empty input\n  bulk.find({ _id: id }).deleteOne();\n}\nawait bulk.execute(); // throws: Batch cannot be empty\n\n// after\nconst ids: unknown[] = [];\nif (ids.length > 0) {\n  const bulk = coll.initializeUnorderedBulkOp();\n  for (const id of ids) bulk.find({ _id: id }).deleteOne();\n  await bulk.execute();\n}","handlingStrategy":"validation","validationCode":"if (myOps.length === 0) {\n  // nothing to do — skip execute entirely\n  return;\n}\nconst bulk = coll.initializeUnorderedBulkOp();\nfor (const op of myOps) /* add ops */;\nawait bulk.execute();","typeGuard":"function hasAny<T>(arr: readonly T[]): arr is [T, ...T[]] {\n  return arr.length > 0;\n}\n\nif (hasAny(myOps)) {\n  // build and execute the bulk\n}","tryCatchPattern":"try {\n  await bulk.execute();\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /Batch cannot be empty/.test(e.message)) {\n    // no-op: nothing to write; swallow or log\n  } else throw e;\n}","preventionTips":["Guard execute() behind a non-empty check on the operations you intend to send.","Skip the entire bulk block when the input list is empty.","Track an 'added any ops?' boolean when using the builder API.","Prefer collection.bulkWrite(ops) guarded by `if (ops.length)`."],"tags":["bulk-write","execute","empty-batch","validation"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}