mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Collection.insertMany() cannot be called with an array that

Error message

Collection.insertMany() cannot be called with an array that has null/undefined values

What it means

Thrown by Collection.insertMany() when the docs array contains one or more null/undefined elements. Internally insertMany maps each doc to { insertOne: { document: doc } } and calls bulkWrite; bulk's raw() rejects null/undefined operations with 'Operation must be an object with an operation key', which insertMany catches and rewrites into this clearer message. It is a MongoInvalidArgumentError surfaced before the bulk is sent to the server.

Source

Thrown at src/collection.ts:335

      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(
          'Collection.insertMany() cannot be called with an array that has null/undefined values'
        );
      }
      throw err;
    }
  }

  /**
   * Perform a bulkWrite operation without a fluent API
   *
   * Legal operation types are
   * - `insertOne`
   * - `replaceOne`
   * - `updateOne`
   * - `updateMany`
   * - `deleteOne`
   * - `deleteMany`
   *

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Filter null/undefined before the call: await collection.insertMany(docs.filter(d => d != null)).
  2. Find and fix the producer of the null/undefined entries so the array is always dense.
  3. If null should mean 'skip', validate with docs.every(d => d != null) and reject early with a descriptive error.
  4. Add a unit test asserting the array has no holes after it is constructed.

Example fix

// before
const docs = rows.map(r => r.isValid ? r.asDocument() : undefined);
await collection.insertMany(docs);
// after
const docs = rows.map(r => r.asDocument()).filter((d): d is NonNullable<typeof d> => d != null);
await collection.insertMany(docs);
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeDocs<T>(docs: (T | null | undefined)[]): T[] {
  const clean = docs.filter((d): d is T => d != null);
  if (clean.length !== docs.length) {
    // optional: log how many were dropped
  }
  return clean;
}
await collection.insertMany(sanitizeDocs(rawDocs));

Type guard

const isDenseDocumentArray = <T>(v: unknown): v is T[] =>
  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 && /null\/undefined values/.test(e.message)) {
    const cleaned = docs.filter(d => d != null);
    return collection.insertMany(cleaned); // or surface a domain error
  }
  throw e;
}

Prevention

When it happens

Trigger: An array built with sparse holes or pushed undefined: docs.push(maybeDoc) where maybeDoc is undefined; JSON arrays containing null literals ([{a:1}, null]); destructuring or mapping that yields undefined for missing keys; mixing documents and null sentinels.

Common situations: Reading rows from a CSV/database where some rows are null and pushing them unfiltered; array built from Object.values on a sparse object; conditional spread that inserts undefined; migrating code that previously tolerated nulls.

Related errors


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