{"record":{"id":"66d5d9b5449f035e","repo":"mongodb/node-mongodb-native","slug":"operation-must-be-an-object-with-an-operation-key","errorCode":null,"errorMessage":"Operation must be an object with an operation key","messagePattern":"Operation must be an object with an operation key","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/bulk/common.ts","lineNumber":1071,"sourceCode":"   * ```\n   */\n  find(selector: Document): FindOperators {\n    if (!selector) {\n      throw new MongoInvalidArgumentError('Bulk find operation must specify a selector');\n    }\n\n    // Save a current selector\n    this.s.currentOp = {\n      selector: selector\n    };\n\n    return new FindOperators(this);\n  }\n\n  /** Specifies a raw operation to perform in the bulk write. */\n  raw(op: AnyBulkWriteOperation): this {\n    if (op == null || typeof op !== 'object') {\n      throw new MongoInvalidArgumentError('Operation must be an object with an operation key');\n    }\n    if ('insertOne' in op) {\n      const forceServerObjectId = this.shouldForceServerObjectId();\n      const document =\n        op.insertOne && op.insertOne.document == null\n          ? // TODO(NODE-6003): remove support for omitting the `documents` subdocument in bulk inserts\n            (op.insertOne as Document)\n          : op.insertOne.document;\n\n      maybeAddIdToDocuments(this.collection, document, { forceServerObjectId });\n\n      return this.addToOperationsList(BatchType.INSERT, document);\n    }\n\n    if ('replaceOne' in op || 'updateOne' in op || 'updateMany' in op) {\n      if ('replaceOne' in op) {\n        if ('q' in op.replaceOne) {\n          throw new MongoInvalidArgumentError('Raw operations are not allowed');","sourceCodeStart":1053,"sourceCodeEnd":1089,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/bulk/common.ts#L1053-L1089","documentation":"Thrown as MongoInvalidArgumentError by BulkOperationBase.raw() (src/bulk/common.ts:1071) when the operation argument is null, undefined, or not an object. raw() dispatches on which operation key (insertOne/updateOne/etc.) is present, so it requires a non-null object containing at least one recognized operation key.","triggerScenarios":"Calling collection.bulkWrite(ops) (which calls raw() per op) where one of the entries in the ops array is null, undefined, a primitive, or an array. Guarded by `if (op == null || typeof op !== 'object')` at src/bulk/common.ts:1070.","commonSituations":"A .map() that returns undefined for some elements, a filtered list that left a hole, JSON.parse of malformed input producing nulls, or accidentally passing the inner payload (e.g. op.insertOne) instead of the wrapper object { insertOne: ... }.","solutions":["Inspect the operations array and ensure every element is a non-null object with exactly one of the recognized keys (insertOne, updateOne, updateMany, replaceOne, deleteOne, deleteMany).","Filter out falsy entries before calling bulkWrite: ops.filter(Boolean).","If a variable holds the inner payload, wrap it: ops.push({ insertOne: { document: doc } })."],"exampleFix":"// before\nawait collection.bulkWrite([\n  undefined,\n  { insertOne: { document: { a: 1 } } }\n]);\n\n// after\nawait collection.bulkWrite(\n  [\n    undefined,\n    { insertOne: { document: { a: 1 } } }\n  ].filter((op): op is NonNullable<typeof op> => op != null)\n);","handlingStrategy":"type-guard","validationCode":"function isBulkOpObject(op: unknown): op is Record<string, unknown> {\n  return op != null && typeof op === 'object' && !Array.isArray(op);\n}\n\nconst cleaned = ops.filter(isBulkOpObject);\nif (cleaned.length !== ops.length) {\n  throw new Error('one or more bulk operations were null/non-object');\n}\nawait coll.bulkWrite(cleaned);","typeGuard":"function isBulkOp(op: unknown): op is Record<string, unknown> {\n  return op != null && typeof op === 'object' && !Array.isArray(op);\n}","tryCatchPattern":"try {\n  await coll.bulkWrite(ops);\n} catch (e) {\n  if (e instanceof MongoInvalidArgumentError && /must be an object/.test(e.message)) {\n    await coll.bulkWrite(ops.filter((o): o is NonNullable<typeof o> => o != null && typeof o === 'object'));\n  } else throw e;\n}","preventionTips":["Filter null/undefined entries out of the ops array before bulkWrite.","Type the ops array as NonNullable<...>[] to surface holes at compile time.","Validate at API boundaries: reject primitives/arrays in the ops list.","Wrap inner payloads as { insertOne: { document: doc } } rather than passing the inner payload directly."],"tags":["bulk-write","raw","validation","typescript"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}