{"id":"29e259707377c2ff","repo":"mongodb/node-mongodb-native","slug":"argument-replacement-must-be-an-object","errorCode":null,"errorMessage":"Argument \"replacement\" must be an object","messagePattern":"Argument \"replacement\" must be an object","errorType":"exception","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/operations/find_and_modify.ts","lineNumber":236,"sourceCode":"    return document;\n  }\n}\n\n/** @internal */\nexport class FindOneAndReplaceOperation extends FindAndModifyOperation {\n  private replacement: Document;\n  constructor(\n    collection: Collection,\n    filter: Document,\n    replacement: Document,\n    options: FindOneAndReplaceOptions\n  ) {\n    if (filter == null || typeof filter !== 'object') {\n      throw new MongoInvalidArgumentError('Argument \"filter\" must be an object');\n    }\n\n    if (replacement == null || typeof replacement !== 'object') {\n      throw new MongoInvalidArgumentError('Argument \"replacement\" must be an object');\n    }\n\n    if (hasAtomicOperators(replacement)) {\n      throw new MongoInvalidArgumentError('Replacement document must not contain atomic operators');\n    }\n\n    super(collection, filter, options);\n    this.replacement = replacement;\n  }\n\n  override buildCommandDocument(\n    connection: Connection,\n    session?: ClientSession\n  ): Document & FindAndModifyCmdBase {\n    const document = super.buildCommandDocument(connection, session);\n    document.update = this.replacement;\n    configureFindAndModifyCmdBaseUpdateOpts(document, this.options);\n    return document;","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/operations/find_and_modify.ts#L218-L254","documentation":"FindOneAndReplaceOperation's constructor (src/operations/find_and_modify.ts:236) requires the `replacement` argument to be a non-null object. The replacement is a full document that substitutes the matched document, so it must be a plain document without update operators. Passing null/undefined/primitive throws a MongoInvalidArgumentError.","triggerScenarios":"Calling collection.findOneAndReplace(filter, null), collection.findOneAndReplace(filter, undefined), or passing a non-object as replacement.","commonSituations":"Omitting the replacement argument, passing a partial update with $set operators (which belongs in findOneAndUpdate), or a variable that resolved to undefined.","solutions":["Pass a full replacement document: collection.findOneAndReplace(filter, { name: 'new', qty: 5 }).","If you need atomic operators like $set, use findOneAndUpdate instead of findOneAndReplace.","Ensure the replacement variable is a defined object before the call."],"exampleFix":"// before\nawait collection.findOneAndReplace({ _id }, { $set: { name: 'x' } }); // wrong API\n\n// after\n// for a full replacement:\nawait collection.findOneAndReplace({ _id }, { name: 'x', qty: 0 });\n// or use findOneAndUpdate for atomic operators:\nawait collection.findOneAndUpdate({ _id }, { $set: { name: 'x' } });","handlingStrategy":"validation","validationCode":"function assertReplacement(doc: unknown): asserts doc is Record<string, unknown> {\n  if (doc == null || typeof doc !== 'object' || Array.isArray(doc)) {\n    throw new TypeError('findOneAndReplace: replacement must be a plain object');\n  }\n}","typeGuard":"const isValidReplacement = (d: unknown): d is Record<string, unknown> =>\n  d != null && typeof d === 'object' && !Array.isArray(d);","tryCatchPattern":null,"preventionTips":["Pass a full replacement document, not an update with operators.","Use findOneAndUpdate if you need $set/$inc/etc.","Validate that the replacement variable is defined before calling."],"tags":["argument-validation","find-one-and-modify","replacement","client-side"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}