mongodb/node-mongodb-native · error · MongoInvalidArgumentError
Argument "operations" must be an array of documents
Error message
Argument "operations" must be an array of documents
What it means
Thrown by Collection.bulkWrite() when the operations argument is not an Array. Each element must be one of the recognized bulk operation shapes (insertOne, updateOne, updateMany, replaceOne, deleteOne, deleteMany). This MongoInvalidArgumentError is raised before the bulk op is built or any connection is checked out.
Source
Thrown at src/collection.ts:367
* - `updateOne`
* - `updateMany`
* - `deleteOne`
* - `deleteMany`
*
* If documents passed in do not contain the **_id** field,
* one will be added to each of the documents missing it by the driver, mutating the document. This behavior
* can be overridden by setting the **forceServerObjectId** flag.
*
* @param operations - Bulk operations to perform
* @param options - Optional settings for the command
* @throws MongoDriverError if operations is not an array
*/
async bulkWrite(
operations: ReadonlyArray<AnyBulkWriteOperation<TSchema>>,
options?: BulkWriteOptions
): Promise<BulkWriteResult> {
if (!Array.isArray(operations)) {
throw new MongoInvalidArgumentError('Argument "operations" must be an array of documents');
}
options = resolveOptions(this, options ?? {});
// TODO(NODE-7071): remove once the client doesn't need to be connected to construct
// bulk operations
const isConnected = this.client.topology != null;
if (!isConnected) {
await autoConnect(this.client);
}
// Create the bulk operation
const bulk: BulkOperationBase =
options.ordered === false
? this.initializeUnorderedBulkOp(options)
: this.initializeOrderedBulkOp(options);
// for each op go through and add to the bulkView on GitHub (pinned to 3366c21a63)
Solutions
- Ensure the argument is always an array: ops = ops ?? []; at the call site.
- Wrap a single operation: bulkWrite(Array.isArray(ops) ? ops : [ops]).
- Guard with Array.isArray(ops) and throw a domain-specific error before calling.
- Type the producer function's return as AnyBulkWriteOperation<T>[] to catch regressions.
Example fix
// before
const ops = condition ? [{ updateOne: {...} }] : undefined;
await collection.bulkWrite(ops);
// after
const ops = condition ? [{ updateOne: {...} }] : [];
await collection.bulkWrite(ops); Defensive patterns
Strategy: type-guard
Validate before calling
function asBulkOps<T>(ops: unknown): T[] {
if (!Array.isArray(ops)) {
throw new TypeError('bulkWrite requires an array of operations');
}
return ops as T[];
}
await collection.bulkWrite(asBulkOps(operations)); Type guard
const isBulkOperationArray = (v: unknown): v is object[] => Array.isArray(v) && v.every(o => o != null && typeof o === 'object');
Try / catch
try {
await collection.bulkWrite(operations);
} catch (e) {
if (e instanceof MongoInvalidArgumentError && /operations.*must be an array/.test(e.message)) {
throw new TypeError('Expected an array of bulk operations');
}
throw e;
} Prevention
- Initialize operation accumulators to [].
- Type dynamic builders as AnyBulkWriteOperation<TSchema>[].
- Avoid conditional assignment that leaves undefined.
When it happens
Trigger: Passing a single operation object instead of an array; passing undefined; passing a generator or custom iterable that is not an Array; passing an array-like object ({length, 0, 1}) that fails Array.isArray.
Common situations: Building operations conditionally and forgetting to initialize the accumulator to []; spreading a possibly-undefined value; refactoring from a fluent bulk to bulkWrite without wrapping; JSON input parsed into an object rather than an array.
Related errors
- Argument "docs" must be an array of documents
- Argument "pipeline" must be an array of aggregation stages
- Update operations require that all atomic operators have def
- Update document requires atomic operators
- Replacement document must not use atomic operators
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/982206892efff534.json.
Report an issue: GitHub.