{"record":{"id":"5985a25b761fd284","repo":"mongodb/node-mongodb-native","slug":"bulkwrite-only-supports-insertone-updateone-upda","errorCode":null,"errorMessage":"bulkWrite only supports insertOne, updateOne, updateMany, deleteOne, deleteMany","messagePattern":"bulkWrite only supports insertOne, updateOne, updateMany, deleteOne, deleteMany","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/bulk/common.ts","lineNumber":1152,"sourceCode":"      }\n      return this.addToOperationsList(\n        BatchType.DELETE,\n        makeDeleteStatement(op.deleteOne.filter, { ...op.deleteOne, limit: 1 })\n      );\n    }\n\n    if ('deleteMany' in op) {\n      if ('q' in op.deleteMany) {\n        throw new MongoInvalidArgumentError('Raw operations are not allowed');\n      }\n      return this.addToOperationsList(\n        BatchType.DELETE,\n        makeDeleteStatement(op.deleteMany.filter, { ...op.deleteMany, limit: 0 })\n      );\n    }\n\n    // otherwise an unknown operation was provided\n    throw new MongoInvalidArgumentError(\n      'bulkWrite only supports insertOne, updateOne, updateMany, deleteOne, deleteMany'\n    );\n  }\n\n  get length(): number {\n    return this.s.currentIndex;\n  }\n\n  get bsonOptions(): BSONSerializeOptions {\n    return this.s.bsonOptions;\n  }\n\n  get writeConcern(): WriteConcern | undefined {\n    return this.s.writeConcern;\n  }\n\n  get batches(): Batch[] {\n    const batches = [...this.s.batches];","sourceCodeStart":1134,"sourceCodeEnd":1170,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/bulk/common.ts#L1134-L1170","documentation":"Thrown as MongoInvalidArgumentError at the end of BulkOperationBase.raw() (src/bulk/common.ts:1152) when the operation object does not match any recognized bulk write operation shape. raw() dispatches on the presence of insertOne/replaceOne/updateOne/updateMany/deleteOne/deleteMany keys; if none is present, it falls through to this catch-all error.","triggerScenarios":"Passing an operation with a typo or unsupported key, e.g. { insert: {...} }, { update: {...} }, { remove: {...} }, or a completely unknown shape like { foo: 1 }. Also triggered by extra/wrapper layers such as { op: { insertOne: {...} } } where the inner shape is nested one level too deep.","commonSituations":"Typos in operation keys, version drift (using a key from an older/newer driver), wrapping ops in an extra object, or building ops from a schema that does not match the bulkWrite input contract.","solutions":["Verify each op has exactly one of: insertOne, updateOne, updateMany, replaceOne, deleteOne, deleteMany.","Check for typos (insert vs insertOne, update vs updateOne) and remove extra wrapper layers.","Log the offending op to see its actual keys before the call."],"exampleFix":"// before\nawait coll.bulkWrite([\n  { insert: { document: { a: 1 } } },\n  { update: { filter: {}, set: { b: 2 } } }\n]);\n\n// after\nawait coll.bulkWrite([\n  { insertOne: { document: { a: 1 } } },\n  { updateOne: { filter: {}, update: { $set: { b: 2 } } } }\n]);","handlingStrategy":"type-guard","validationCode":"const SUPPORTED = new Set(['insertOne','updateOne','updateMany','replaceOne','deleteOne','deleteMany']);\n\nfunction isSupportedBulkOp(op: unknown): op is Record<string, unknown> {\n  if (op == null || typeof op !== 'object') return false;\n  const keys = Object.keys(op);\n  return keys.length === 1 && SUPPORTED.has(keys[0]);\n}\n\nconst bad = ops.filter(o => !isSupportedBulkOp(o));\nif (bad.length) {\n  throw new Error('unsupported bulk op keys: ' + bad.map(o => Object.keys(o)[0]).join(', '));\n}\nawait coll.bulkWrite(ops);","typeGuard":"type AnyBulkOp =\n  | { insertOne: { document: Record<string, unknown> } }\n  | { updateOne: { filter: Record<string, unknown>; update: Record<string, unknown> | Record<string, unknown>[] } }\n  | { updateMany: { filter: Record<string, unknown>; update: Record<string, unknown> | Record<string, unknown>[] } }\n  | { replaceOne: { filter: Record<string, unknown>; replacement: Record<string, unknown> } }\n  | { deleteOne: { filter: Record<string, unknown> } }\n  | { deleteMany: { filter: Record<string, unknown> } };\n\nconst SUPPORTED = new Set(['insertOne','updateOne','updateMany','replaceOne','deleteOne','deleteMany']);\nfunction isAnyBulkOp(op: unknown): op is AnyBulkOp {\n  if (op == null || typeof op !== 'object') return false;\n  const keys = Object.keys(op);\n  return keys.length === 1 && SUPPORTED.has(keys[0]);\n}","tryCatchPattern":"try {\n  await coll.bulkWrite(ops);\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /only supports/.test(e.message)) {\n    // log each op's keys to find the typo / unknown shape, then fix and retry\n    console.error(ops.map(o => Object.keys(o)));\n  }\n  throw e;\n}","preventionTips":["Validate each op has exactly one supported key before calling bulkWrite.","Type the ops array as AnyBulkWriteOperation[] to surface shape errors at compile time.","Watch for typos (insert vs insertOne) and extra wrapper layers.","Log op keys in tests so shape regressions show up early."],"tags":["bulk-write","operation-shape","validation"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}