mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Operation passed in cannot be an Array
Error message
Operation passed in cannot be an Array
What it means
Thrown by UnorderedBulkOperation.addToOperationsList() when the document argument is an array. Each call must receive a single document; list inputs must be iterated. Mirror of the ordered variant's guard.
Source
Thrown at src/bulk/unordered.ts:103
// New batch if we exceed the max batch op size
this.s.currentBatch.size + 1 >= this.s.maxWriteBatchSize ||
// New batch if we exceed the maxBatchSizeBytes. Only matters if batch already has a doc,
// since we can't sent an empty batch
(this.s.currentBatch.size > 0 &&
this.s.currentBatch.sizeBytes + maxKeySize + bsonSize >= this.s.maxBatchSizeBytes) ||
// New batch if the new op does not have the same op type as the current batch
this.s.currentBatch.batchType !== batchType
) {
// Save the batch to the execution stack
this.s.batches.push(this.s.currentBatch);
// Create a new batch
this.s.currentBatch = new Batch(batchType, this.s.currentIndex);
}
// We have an array of documents
if (Array.isArray(document)) {
throw new MongoInvalidArgumentError('Operation passed in cannot be an Array');
}
this.s.currentBatch.operations.push(document);
if (buffer != null) this.s.currentBatch.serializedOperations.push(buffer);
this.s.currentBatch.originalIndexes.push(this.s.currentIndex);
this.s.currentIndex = this.s.currentIndex + 1;
// Save back the current Batch to the right type
if (batchType === BatchType.INSERT) {
this.s.currentInsertBatch = this.s.currentBatch;
this.s.bulkResult.insertedIds.push({
index: this.s.bulkResult.insertedIds.length,
_id: (document as Document)._id
});
} else if (batchType === BatchType.UPDATE) {
this.s.currentUpdateBatch = this.s.currentBatch;
} else if (batchType === BatchType.DELETE) {
this.s.currentRemoveBatch = this.s.currentBatch;View on GitHub (pinned to 3366c21a63)
Solutions
- Call addToOperationsList once per document.
- Use collection.bulkWrite(ops) to let the driver iterate the list.
Example fix
// before addToOperationsList(BatchType.INSERT, [docA, docB]); // after for (const doc of [docA, docB]) addToOperationsList(BatchType.INSERT, doc);
Defensive patterns
Strategy: type-guard
Validate before calling
function assertSingleDoc(doc) {
if (Array.isArray(doc)) {
throw new TypeError('addToOperationsList expects a single document, not an array');
}
} Type guard
function isSingleDocument(doc) {
return doc != null && typeof doc === 'object' && !Array.isArray(doc);
} Try / catch
try {
addToOperationsList(batchType, doc);
} catch (e) {
if (/cannot be an Array/.test(e.message)) {
for (const d of doc) addToOperationsList(batchType, d);
}
} Prevention
- Always iterate lists and enqueue one document per call.
- Prefer collection.bulkWrite(ops) over internal addToOperationsList.
When it happens
Trigger: Internally calling addToOperationsList(batchType, [...]) with an array. Custom subclasses or middleware that pass arrays.
Common situations: Internal API misuse; middleware that batches documents into a single call.
Related errors
- Operation passed in cannot be an Array
- Update document requires atomic operators
- Replacement document must not use atomic operators
- Bulk find operation must specify a selector
- Operation must be an object with an operation key
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/40a693d1128c836c.json.
Report an issue: GitHub.