{"record":{"id":"7ff1cc68a60333a5","repo":"Automattic/mongoose","slug":"bulkwrite-failed-with-validationerrors-length-m-7ff1cc","errorCode":null,"errorMessage":"bulkWrite failed with ${validationErrors.length} Mongoose validation errors: ${preview}","messagePattern":"bulkWrite failed with (.+?) Mongoose validation errors: (.+?)","errorType":"exception","errorClass":"MongooseBulkWriteError","httpStatus":null,"severity":"error","filePath":"lib/model.js","lineNumber":3526,"sourceCode":"            }\n            resolve();\n          });\n        });\n      }));\n      validOpIndexes = validOpIndexes.filter(index => index != null);\n    } else {\n      validOpIndexes = ops.map((op, i) => i);\n    }\n\n    validationErrors = validationErrors.\n      sort((v1, v2) => v1.index - v2.index).\n      map(v => v.error);\n\n    const validOps = validOpIndexes.sort((a, b) => a - b).map(index => ops[index]);\n\n    if (validOps.length === 0) {\n      if (options.throwOnValidationError && validationErrors.length) {\n        throw new MongooseBulkWriteError(\n          validationErrors,\n          results,\n          res,\n          'bulkWrite'\n        );\n      }\n      const BulkWriteResult = this.base.driver.get().BulkWriteResult;\n      const bulkWriteResult = new BulkWriteResult(getDefaultBulkwriteResult(), false);\n      bulkWriteResult.result = getDefaultBulkwriteResult();\n      decorateBulkWriteResult(bulkWriteResult, validationErrors, results);\n      return bulkWriteResult;\n    }\n\n    let error;\n    [res, error] = await this.$__collection.bulkWrite(validOps, options).\n      then(res => ([res, null])).\n      catch(error => ([null, error]));\n","sourceCodeStart":3508,"sourceCodeEnd":3544,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/model.js#L3508-L3544","documentation":"Mongoose casts bulkWrite operations against the schema (insertOne/replaceOne documents, updateOne filters/updates) and collects failures as validationErrors with their op indexes. When zero operations are valid and options.throwOnValidationError is true, Mongoose throws MongooseBulkWriteError with this message before any write is sent; without the option it returns a synthesized BulkWriteResult decorated with the validation errors (check res.mongoose?.validationErrors).","triggerScenarios":"await Model.bulkWrite([{ insertOne: { document: { /* missing required */ } } }, ...], { throwOnValidationError: true }) where every op fails casting/validation.","commonSituations":"Bulk ETL jobs feeding unvalidated external data into insertOne/replaceOne/updateOne ops; enabling throwOnValidationError on a pipeline whose upstream schema changed (new required field) so all ops now fail.","solutions":["Read err.validationErrors: entries carry the failing op's index and the underlying ValidatorError/CastError; fix those ops or the data producing them","Pre-validate documents with new Model(d).validateSync() before building ops, and drop/report invalid ones","If skipping invalid ops is desired, omit throwOnValidationError and inspect res.mongoose.validationErrors on the returned result instead","Verify the ops match the current schema after adding required fields or stricter enums"],"exampleFix":"// before\nconst ops = rows.map(r => ({ insertOne: { document: r } }));\nawait User.bulkWrite(ops, { throwOnValidationError: true }); // every op invalid -> throws\n\n// after\nconst ops = rows\n  .map(r => ({ doc: new User(r), err: new User(r).validateSync() }))\n  .filter(x => !x.err)\n  .map(x => ({ insertOne: { document: x.doc } }));\nawait User.bulkWrite(ops);","handlingStrategy":"validation","validationCode":"function buildValidatedOps(Model, rows) {\n  const ops = [];\n  const invalid = [];\n  rows.forEach((r, i) => {\n    const doc = new Model(r);\n    const err = doc.validateSync();\n    if (err) invalid.push({ index: i, err });\n    else ops.push({ insertOne: { document: doc } });\n  });\n  if (ops.length === 0) throw new Error('no valid ops', { cause: invalid[0]?.err });\n  return { ops, invalid };\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await Model.bulkWrite(ops, { throwOnValidationError: true });\n} catch (err) {\n  if (err.name === 'MongooseBulkWriteError') {\n    for (const v of err.validationErrors) { /* v.index = failing op, v.message = why */ }\n  } else throw err;\n}","preventionTips":["Validate documents before assembling bulkWrite ops; casting happens before any write","When skipping invalid ops is fine, check res.mongoose?.validationErrors on the returned result","Re-validate ETL pipelines after any schema tightening (new required fields, stricter enums)"],"tags":["mongoose","bulkwrite","validation","bulk","casting"],"backgroundTag":"schema-validation-failed","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}