Automattic/mongoose · error · MongooseBulkWriteError

insertMany failed with ${validationErrors.length} Mongoose v

Error message

insertMany failed with ${validationErrors.length} Mongoose validation errors: ${preview}

What it means

During insertMany, documents that fail schema validation are separated into validationErrors and valid ones into docAttributes. When zero documents pass validation and options.throwOnValidationError is true (requires ordered: false), Mongoose throws MongooseBulkWriteError with this message, carrying .validationErrors (each with the failing document's index and ValidatorError details). Without throwOnValidationError, insertMany silently returns [] (or an acknowledged result with insertedCount 0), which is why the option exists.

Source

Thrown at lib/model.js:3152

      doc.initializeTimestamps(timestamps);
    }
    docObjects.push(doc.$__hasOnlyPrimitiveValues() ? doc.$__toObjectShallow() : doc.toObject(internalToObjectOptions));
  }

  // Make sure validation errors are in the same order as the
  // original documents, so if both doc1 and doc2 both fail validation,
  // `Model.insertMany([doc1, doc2])` will always have doc1's validation
  // error before doc2's. Re: gh-12791.
  if (validationErrors.length > 0 && ordered === false) {
    validationErrors.sort((err1, err2) => {
      return err1.index - err2.index;
    });
  }

  // Quickly escape while there aren't any valid docAttributes
  if (docAttributes.length === 0) {
    if (throwOnValidationError) {
      throw new MongooseBulkWriteError(
        validationErrors,
        results,
        null,
        'insertMany'
      );
    }
    if (rawResult) {
      const res = {
        acknowledged: true,
        insertedCount: 0,
        insertedIds: {}
      };
      decorateBulkWriteResult(res, validationErrors, validationErrors);
      return res;
    }
    return [];
  }

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Inspect err.validationErrors: each entry has .index (position in the input array) and .message identifying the failed path and rule; fix the source data or schema accordingly
  2. Pre-validate the batch before insertMany: const errs = docs.map(d => new Model(d).validateSync()); and filter/handle invalid entries
  3. If skipping invalid docs is acceptable, omit throwOnValidationError (default false) and check the returned array length / insertedCount
  4. Clean the data at ingestion: coerce types, fill defaults, validate enum values before the bulk write

Example fix

// before
await User.insertMany(rows, { ordered: false, throwOnValidationError: true }); // all rows invalid -> throws

// after
const valid = [];
const invalid = [];
for (const row of rows) {
  const doc = new User(row);
  const err = doc.validateSync();
  (err ? invalid : valid).push(err ? { row, err } : doc);
}
await User.insertMany(valid, { ordered: false });
// report `invalid` to the caller
Defensive patterns

Strategy: validation

Validate before calling

function prevalidateBatch(Model, docs) {
  return docs.reduce(({ valid, invalid }, d, i) => {
    const err = new Model(d).validateSync();
    if (err) invalid.push({ index: i, err }); else valid.push(d);
    return { valid, invalid };
  }, { valid: [], invalid: [] });
}
const { valid, invalid } = prevalidateBatch(Model, docs);
if (valid.length === 0) throw new Error('entire batch invalid', { cause: invalid[0].err });
await Model.insertMany(valid, { ordered: false });

Try / catch

try {
  await Model.insertMany(docs, { ordered: false, throwOnValidationError: true });
} catch (err) {
  if (err.name === 'MongooseBulkWriteError') {
    for (const v of err.validationErrors) {
      // v.index -> position in input, v.message -> failed path + rule
    }
  } else throw err;
}

Prevention

When it happens

Trigger: await Model.insertMany(docs, { ordered: false, throwOnValidationError: true }) where every document fails validation (missing required field, enum mismatch, custom validator rejection).

Common situations: Bulk imports of CSV/JSON data where required fields are absent or values fail enum/custom validators; enabling throwOnValidationError to stop silently dropping invalid rows and then hitting fully invalid batches.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/1b1d982b67c1a503. Report an issue: GitHub.