mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Argument "docs" must be an array of documents

Error message

Argument "docs" must be an array of documents

What it means

Thrown by Collection.insertMany() when the first argument is not an Array. The driver wraps each provided document into an { insertOne: { document } } bulk operation, so it must iterate the input; a non-iterable value cannot be processed. This is a MongoInvalidArgumentError raised before any network call. The TypeScript signature already requires ReadonlyArray<OptionalUnlessRequiredId<TSchema>>, so this signals a type-safety escape (any/unknown) or a runtime-only caller.

Source

Thrown at src/collection.ts:317

        resolveOptions(this, options)
      ) as TODO_NODE_3286
    );
  }

  /**
   * Inserts an array of documents into MongoDB. 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 docs - The documents to insert
   * @param options - Optional settings for the command
   */
  async insertMany(
    docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,
    options?: BulkWriteOptions
  ): Promise<InsertManyResult<TSchema>> {
    if (!Array.isArray(docs)) {
      throw new MongoInvalidArgumentError('Argument "docs" must be an array of documents');
    }
    options = resolveOptions(this, options ?? {});

    const acknowledged = WriteConcern.fromOptions(options)?.w !== 0;

    try {
      const res = await this.bulkWrite(
        docs.map(doc => ({ insertOne: { document: doc } })),
        options
      );
      return {
        acknowledged,
        insertedCount: res.insertedCount,
        insertedIds: res.insertedIds
      };
    } catch (err) {
      if (err && err.message === 'Operation must be an object with an operation key') {
        throw new MongoInvalidArgumentError(

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Wrap the value in an array at the call site: insertMany(Array.isArray(docs) ? docs : [docs]).
  2. If building the array dynamically, default it: await collection.insertMany(docs ?? []).
  3. Add an Array.isArray(docs) guard before calling insertMany and surface a clearer error to your caller.
  4. Enable strict TypeScript typing on the caller so the non-array value is caught at compile time.

Example fix

// before
await collection.insertMany(req.body);
// after
await collection.insertMany(Array.isArray(req.body) ? req.body : [req.body]);
Defensive patterns

Strategy: type-guard

Validate before calling

function asInsertManyDocs<T>(docs: unknown): T[] {
  if (!Array.isArray(docs)) {
    throw new TypeError('insertMany requires an array');
  }
  return docs as T[];
}
// usage:
await collection.insertMany(asInsertManyDocs(maybeDocs));

Type guard

const isDocumentArray = (v: unknown): v is Record<string, unknown>[] =>
  Array.isArray(v) && v.every(d => d != null && typeof d === 'object' && !Array.isArray(d));

Try / catch

try {
  await collection.insertMany(docs);
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /must be an array of documents/.test(e.message)) {
    throw new TypeError('Expected an array of documents, got: ' + typeof docs);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling collection.insertMany(singleDoc) passing a single object instead of an array; passing undefined/null when the array is conditionally built; passing a Map, Set, or other iterable that is not an Array (Array.isArray returns false); passing a Promise that resolved to an array but was not awaited.

Common situations: JavaScript callers that forgot to wrap a single document in []; a value sourced from JSON.parse or an untyped API response fed directly in; refactoring from insertOne to insertMany without adjusting the call site; awaiting an async iterator's result incorrectly.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/e0fb990ab93f3ccb.json. Report an issue: GitHub.