{"action":"created","issue":{"url":"https://api.github.com/repos/LearnBoost/mongoose/issues/2519","labels_url":"https://api.github.com/repos/LearnBoost/mongoose/issues/2519/labels{/name}","comments_url":"https://api.github.com/repos/LearnBoost/mongoose/issues/2519/comments","events_url":"https://api.github.com/repos/LearnBoost/mongoose/issues/2519/events","html_url":"https://github.com/LearnBoost/mongoose/issues/2519","id":51173767,"number":2519,"title":"Model.findOneAndUpdate fails when using option upsert: true","user":{"login":"benkroeger","id":7782055,"avatar_url":"https://avatars.githubusercontent.com/u/7782055?v=3","gravatar_id":"","url":"https://api.github.com/users/benkroeger","html_url":"https://github.com/benkroeger","followers_url":"https://api.github.com/users/benkroeger/followers","following_url":"https://api.github.com/users/benkroeger/following{/other_user}","gists_url":"https://api.github.com/users/benkroeger/gists{/gist_id}","starred_url":"https://api.github.com/users/benkroeger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benkroeger/subscriptions","organizations_url":"https://api.github.com/users/benkroeger/orgs","repos_url":"https://api.github.com/users/benkroeger/repos","events_url":"https://api.github.com/users/benkroeger/events{/privacy}","received_events_url":"https://api.github.com/users/benkroeger/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/LearnBoost/mongoose/milestones/22","labels_url":"https://api.github.com/repos/LearnBoost/mongoose/milestones/22/labels","id":893197,"number":22,"title":"4.0.0-rc0","description":"","creator":{"login":"vkarpov15","id":1620265,"avatar_url":"https://avatars.githubusercontent.com/u/1620265?v=3","gravatar_id":"","url":"https://api.github.com/users/vkarpov15","html_url":"https://github.com/vkarpov15","followers_url":"https://api.github.com/users/vkarpov15/followers","following_url":"https://api.github.com/users/vkarpov15/following{/other_user}","gists_url":"https://api.github.com/users/vkarpov15/gists{/gist_id}","starred_url":"https://api.github.com/users/vkarpov15/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkarpov15/subscriptions","organizations_url":"https://api.github.com/users/vkarpov15/orgs","repos_url":"https://api.github.com/users/vkarpov15/repos","events_url":"https://api.github.com/users/vkarpov15/events{/privacy}","received_events_url":"https://api.github.com/users/vkarpov15/received_events","type":"User","site_admin":false},"open_issues":10,"closed_issues":10,"state":"open","created_at":"2014-12-05T17:14:46Z","updated_at":"2015-01-02T16:02:21Z","due_on":"2015-01-24T05:00:00Z","closed_at":null},"comments":2,"created_at":"2014-12-06T06:46:00Z","updated_at":"2015-01-02T16:02:21Z","closed_at":null,"body":"When using findOneAndUpdate in combination with upsert = true, the mongodb driver throws a MongoError:\r\n\r\n```\r\nMongoError: remove and upsert can't co-exist\r\n```\r\n\r\nThis is what I'm trying to execute:\r\n\r\n``` javascript\r\nreturn Tag.findOneAndUpdate({\r\n        $and: [{\r\n          term: tag.term\r\n        }, {\r\n          category: tag.category\r\n        }]\r\n      }, {\r\n        $setOnInsert: {\r\n          term: tag.term,\r\n          category: tag.category\r\n        }\r\n      }, {\r\n        select: {\r\n          _id: 1\r\n        },\r\n        new: true,\r\n        upsert: true\r\n      }).exec('findOneAndUpdate');\r\n```\r\n\r\nThe reason this fails is, that the mongodb dirver sets the option \"remove\" to 1 when options.remove resolves to \"true:\r\n\r\nmongodb/lib/mongodb/collection/core.js: Line 747\r\n\r\n``` javascript\r\nqueryObject.remove = options.remove ? 1 : 0;\r\n```\r\n\r\nModel.findOneAndUpdate results in an internal call to Query.prototype._findAndModify, where the opts object is created like this\r\n\r\nmongoose/lib/query.js: Line 1502\r\n\r\n``` javascript\r\nopts = this._optionsForExec(model)\r\n```\r\n\r\nafter which opts.remove is set to a function. I assume, this is some sort of getter function from the model?\r\n\r\nI've added a conditional overwriting of opts.remove in case that opts.upsert resolves to \"true\"\r\n\r\nmongoose/lib/query.js: Line 1508\r\n\r\n``` javascript\r\nif (!('upsert' in opts)) opts.upsert = false;\r\nif (opts.upsert) {\r\n  opts.remove = false;\r\n}\r\n```\r\n\r\nwhich solved my problem.\r\nHowever, I don't know if this will have any side-effects.\r\n\r\nVerified, that the same issue exists on 3.8.20"},"comment":{"url":"https://api.github.com/repos/LearnBoost/mongoose/issues/comments/68537204","html_url":"https://github.com/LearnBoost/mongoose/issues/2519#issuecomment-68537204","issue_url":"https://api.github.com/repos/LearnBoost/mongoose/issues/2519","id":68537204,"user":{"login":"vkarpov15","id":1620265,"avatar_url":"https://avatars.githubusercontent.com/u/1620265?v=3","gravatar_id":"","url":"https://api.github.com/users/vkarpov15","html_url":"https://github.com/vkarpov15","followers_url":"https://api.github.com/users/vkarpov15/followers","following_url":"https://api.github.com/users/vkarpov15/following{/other_user}","gists_url":"https://api.github.com/users/vkarpov15/gists{/gist_id}","starred_url":"https://api.github.com/users/vkarpov15/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vkarpov15/subscriptions","organizations_url":"https://api.github.com/users/vkarpov15/orgs","repos_url":"https://api.github.com/users/vkarpov15/repos","events_url":"https://api.github.com/users/vkarpov15/events{/privacy}","received_events_url":"https://api.github.com/users/vkarpov15/received_events","type":"User","site_admin":false},"created_at":"2015-01-02T16:02:21Z","updated_at":"2015-01-02T16:02:21Z","body":"@benkroeger this change went in to master branch, and so it's in the unstable 3.9.7 release. I won't merge master into 3.8.x. However, I can backport this fix in for 3.8.22, thanks for reminding me."}}