{"id":"1b398d0afa50f732","repo":"mongodb/node-mongodb-native","slug":"operation-passed-in-cannot-be-an-array","errorCode":null,"errorMessage":"Operation passed in cannot be an Array","messagePattern":"Operation passed in cannot be an Array","errorType":"validation","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/bulk/ordered.ts","lineNumber":88,"sourceCode":"\n      // Create a new batch\n      this.s.currentBatch = new Batch(batchType, this.s.currentIndex);\n\n      // Reset the current size trackers\n      this.s.currentBatchSize = 0;\n      this.s.currentBatchSizeBytes = 0;\n    }\n\n    if (batchType === BatchType.INSERT) {\n      this.s.bulkResult.insertedIds.push({\n        index: this.s.currentIndex,\n        _id: (document as Document)._id\n      });\n    }\n\n    // We have an array of documents\n    if (Array.isArray(document)) {\n      throw new MongoInvalidArgumentError('Operation passed in cannot be an Array');\n    }\n\n    this.s.currentBatch.originalIndexes.push(this.s.currentIndex);\n    this.s.currentBatch.operations.push(document);\n    if (buffer != null) this.s.currentBatch.serializedOperations.push(buffer);\n    this.s.currentBatchSize += 1;\n    this.s.currentBatchSizeBytes += maxKeySize + bsonSize;\n    this.s.currentIndex += 1;\n    return this;\n  }\n}\n","sourceCodeStart":70,"sourceCodeEnd":100,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/bulk/ordered.ts#L70-L100","documentation":"Thrown by OrderedBulkOperation.addToOperationsList() when the document argument is an array. Each addToOperationsList call must receive a single operation document; arrays of operations must be enqueued one at a time. The check runs after size validation, so the error is reached for array inputs that are not already rejected.","triggerScenarios":"Internally calling addToOperationsList(batchType, [...]) with an array. A code path that passes a list of documents instead of iterating. Generally not user-reachable via the fluent API but possible via internal misuse or extensions.","commonSituations":"Custom subclasses or middleware that intercept addToOperationsList and pass arrays; misuse of internal APIs.","solutions":["Iterate and call addToOperationsList once per document.","Use bulk.insert(doc) in a loop rather than passing the whole list.","If you have a list, use collection.bulkWrite(ops) which handles iteration internally."],"exampleFix":"// before\naddToOperationsList(BatchType.INSERT, [docA, docB]);\n\n// after\nfor (const doc of [docA, docB]) addToOperationsList(BatchType.INSERT, doc);","handlingStrategy":"type-guard","validationCode":"function assertSingleDoc(doc) {\n  if (Array.isArray(doc)) {\n    throw new TypeError('addToOperationsList expects a single document, not an array');\n  }\n}","typeGuard":"function isSingleDocument(doc) {\n  return doc != null && typeof doc === 'object' && !Array.isArray(doc);\n}","tryCatchPattern":"try {\n  addToOperationsList(batchType, doc);\n} catch (e) {\n  if (/cannot be an Array/.test(e.message)) {\n    for (const d of doc) addToOperationsList(batchType, d);\n  }\n}","preventionTips":["Always iterate and enqueue one document at a time.","Use the public collection.bulkWrite(ops) API rather than internal addToOperationsList."],"tags":["bulk-write","ordered","internal","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}