{"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":"validation","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/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/bulk/common.ts#L1183-L1219","documentation":"Thrown by BulkOperationBase.execute() when no operations were ever added (this.s.batches is empty). Calling execute() on a bulk op where find()/insert()/raw() were never invoked is a programming error; the server would reject an empty batch anyway.","triggerScenarios":"Calling await bulk.execute() on a freshly initialized bulk op without adding any operations. Building operations conditionally such that none are added for an empty input list.","commonSituations":"Empty input arrays processed in a loop that adds zero ops; early-return logic that skips all op additions but still reaches execute(); tests that scaffold a bulk op but never populate it.","solutions":["Guard execute() with a check: if (bulk.length === 0) return; before calling execute().","Validate the input list is non-empty before initializing the bulk op.","Use collection.bulkWrite(ops) and short-circuit when ops.length === 0."],"exampleFix":"// before\nconst bulk = coll.initializeUnorderedBulkOp();\nfor (const op of ops) bulk.raw(op); // ops is []\nawait bulk.execute(); // throws\n\n// after\nif (ops.length === 0) return;\nconst bulk = coll.initializeUnorderedBulkOp();\nfor (const op of ops) bulk.raw(op);\nawait bulk.execute();","handlingStrategy":"validation","validationCode":"function executeIfNonEmpty(bulk) {\n  if (bulk.length === 0) return null;\n  return bulk.execute();\n}","typeGuard":"function bulkHasOps(bulk) {\n  return bulk != null && typeof bulk.length === 'number' && bulk.length > 0;\n}","tryCatchPattern":"try {\n  await bulk.execute();\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /Batch cannot be empty/.test(e.message)) {\n    return; // nothing to do\n  }\n  throw e;\n}","preventionTips":["Short-circuit when the input list is empty before initializing a bulk op.","Check bulk.length before execute().","Prefer collection.bulkWrite(ops) and guard with if (ops.length === 0) return."],"tags":["bulk-write","validation","empty-state","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}