{"id":"449923bb9cf1f6f1","repo":"mongodb/node-mongodb-native","slug":"replacement-document-must-not-contain-atomic-opera-449923","errorCode":null,"errorMessage":"Replacement document must not contain atomic operators","messagePattern":"Replacement document must not contain atomic operators","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/operations/update.ts","lineNumber":235,"sourceCode":"  upsert?: boolean;\n  /** Map of parameter names and values that can be accessed using $$var (requires MongoDB 5.0). */\n  let?: Document;\n  /** Specifies the sort order for the documents matched by the filter. */\n  sort?: Sort;\n}\n\n/** @internal */\nexport class ReplaceOneOperation extends UpdateOperation {\n  constructor(\n    ns: MongoDBCollectionNamespace,\n    filter: Document,\n    replacement: Document,\n    options: ReplaceOptions\n  ) {\n    super(ns, [makeUpdateStatement(filter, replacement, { ...options, multi: false })], options);\n\n    if (hasAtomicOperators(replacement)) {\n      throw new MongoInvalidArgumentError('Replacement document must not contain atomic operators');\n    }\n  }\n\n  override handleOk(\n    response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>\n  ): UpdateResult {\n    const res = super.handleOk(response);\n\n    // @ts-expect-error Explain typing is broken\n    if (this.explain != null) return res;\n    if (res.code) throw new MongoServerError(res);\n    if (res.writeErrors) throw new MongoServerError(res.writeErrors[0]);\n\n    return {\n      acknowledged: this.writeConcern?.w !== 0,\n      modifiedCount: res.nModified ?? res.n,\n      upsertedId:\n        Array.isArray(res.upserted) && res.upserted.length > 0 ? res.upserted[0]._id : null,","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/operations/update.ts#L217-L253","documentation":"Thrown by ReplaceOneOperation's constructor when the replacement argument passed to collection.replaceOne() DOES contain atomic operators. replaceOne performs a full-document replacement and must not use $set/$inc/etc.; the replacement is a plain document with the new field values. This is the inverse check from updateOne. MongoInvalidArgumentError.","triggerScenarios":"collection.replaceOne(filter, { $set: { ... } }) - the caller used replacement semantics but supplied update-operator syntax. Also happens when copy-pasting an updateOne call and only changing the method name.","commonSituations":"Renaming updateOne to replaceOne without removing the operators; mixing up the two operations' contracts; building a generic helper that assumes operators are always wanted.","solutions":["Remove $ operators: pass the full target document, e.g. replaceOne(filter, { name: 'x', status: 1 }).","If you actually want partial mutation with operators, use collection.updateOne() instead of replaceOne().","Remember: replaceOne = whole document; updateOne = operators (or pipeline).","Audit shared write-helper code that branches between the two."],"exampleFix":"// before\nawait collection.replaceOne({ _id: 1 }, { $set: { name: 'x' } });\n// after - choose one:\nawait collection.replaceOne({ _id: 1 }, { name: 'x' }); // full replace\n// or\nawait collection.updateOne({ _id: 1 }, { $set: { name: 'x' } }); // partial update","handlingStrategy":"validation","validationCode":"function isReplacementDoc(doc) {\n  return doc != null && typeof doc === 'object' && !Array.isArray(doc) &&\n    !Object.keys(doc).some(k => k.startsWith('$'));\n}\nif (!isReplacementDoc(replacement)) throw new Error('replaceOne replacement must not use $ operators');\nawait collection.replaceOne(filter, replacement);","typeGuard":"function isReplacementDoc(doc): doc is Record<string, unknown> {\n  return doc != null && typeof doc === 'object' && !Array.isArray(doc) &&\n    !Object.keys(doc).some(k => k.startsWith('$'));\n}","tryCatchPattern":null,"preventionTips":["Keep replaceOne and updateOne code paths separate; don't share operator-tainted objects.","Remember replaceOne = whole plain document.","Review any generic 'write' helper that picks the method dynamically."],"tags":["update","replace","validation","argument-error"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}