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
- 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
- Pre-validate the batch before insertMany: const errs = docs.map(d => new Model(d).validateSync()); and filter/handle invalid entries
- If skipping invalid docs is acceptable, omit throwOnValidationError (default false) and check the returned array length / insertedCount
- 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
- Dry-run batches through validateSync() before insertMany when data quality is uncertain
- Prefer throwOnValidationError: true with ordered: false over silent drops so bad rows are visible
- Add schema-level integration tests that exercise the same validators as production payloads
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
- Model.insertMany() no longer accepts a callback
- bulkWrite failed with ${validationErrors.length} Mongoose va
- ${operation} failed with ${validationErrors.length} Mongoose
- Arguments must be aggregate pipeline operators
- Aggregate `near()` argument must have a `near` property
AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21).
Data as JSON: /api/errors/1b1d982b67c1a503.
Report an issue: GitHub.