101

This error happens when I tried to update upsert item:

Updating the path 'x' would create a conflict at 'x'
Ashh
  • 44,693
  • 14
  • 105
  • 132
zored
  • 2,718
  • 3
  • 19
  • 23

8 Answers8

88

Field should appear either in $set, or in $setOnInsert. Not in both.

zored
  • 2,718
  • 3
  • 19
  • 23
  • 46
    This doesn't make sense. "$set" happens if the document is found, "$setOnInsert" if the document is not found. There's no conflict since both will never be applied at the same time. If you can't use both on the same field, that kind of defeats the purpose, no? – Charles Langlois Feb 20 '19 at 14:48
  • 21
    `$set` happens if the document is found *and* if it's not found. Therefore it conflicts in "not found" state on `$setOnInsert` and `{upsert: true}`. Seems like MongoDB developers could not define priority of one over another :) – zored Feb 25 '19 at 20:23
  • 12
    Yeah, I realized that. There should really be a "$setOnUpdate" operator. – Charles Langlois Feb 25 '19 at 21:25
  • 1
    As the mongodb document, it applies the $set and $setOnInsert operations to this document. https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/ – Luan Nguyen May 06 '20 at 18:48
  • 1
    Just yeah, don't duplicate fields. No one have mentioned that, but $setOnInsert is actually adding those fields to update doc. Just specify which fields you want to be inserted on insert and update doc excluding properties from insert doc. – Somebody Sep 22 '20 at 14:18
  • 4
    at least the error message could have been better – rehman_00001 Jan 03 '21 at 09:55
  • 8
    But what if I want to insert a document if it doesn't exist, and update just one field if it exists? Both must have the `x` field. – emremrah Aug 29 '22 at 14:40
  • @emremrah at lease in javascript you can do `$set:{x: defaultValue, ...data}` without the `$setOnInsert`, so if x is in data then it would override the default value. – ziv Aug 08 '23 at 06:50
19

I had the same problem while performing an update query using PyMongo.
I was trying to do:


> db.people.update( {'name':'lmn'}, { $inc : { 'key1' : 2 }, $set: { 'key1' : 5 }})

Notice that here I'm trying to update the value of key1 from two MongoDB Update Operators.

This basically happens when you try to update the value of a same key with more than one MongoDB Update Operators within the same query.

You can find a list of Update Operators over here

saintlyzero
  • 1,632
  • 2
  • 18
  • 26
13

If you pass the same key in $set and in $unset when updating an item, you will get that error.

For example:

const body = {
   _id: '47b82d36f33ad21b90'
   name: 'John',
   lastName: 'Smith'
}

MyModel.findByIdAndUpdate(body._id, { $set: body, $unset: {name: 1}})

// Updating the path 'name' would create a conflict at 'name'
T-Me
  • 1,814
  • 1
  • 9
  • 22
RodrigoNOFX
  • 143
  • 1
  • 5
13

You cannot have the same path referenced more than once in an update. For example, even though the below would result in something logical, MongoDB will not allow it.

db.getCollection("user").updateOne(
  {_id: ...},
  {$set: {'address': {state: 'CA'}, 'address.city' : 'San Diego'}}
)

You would get the following error:

Updating the path 'address.city' would create a conflict at 'address'
David
  • 606
  • 6
  • 11
8
db.products.update(
  { _id: 1 },
  {
     $set: { item: "apple" },
     $setOnInsert: { defaultQty: 100 }
  },
  { upsert: true }
)

Below is the key explanation to the issue:

MongoDB creates a new document with _id equal to 1 from the condition, and then applies the $set AND $setOnInsert operations to this document.

If you want a field value is set or updated regardless of insertion or update, use it in $set. If you want it to be set only on insertion, use it in $setOnInsert.

Here is the example: https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/#example

Onur Demir
  • 708
  • 2
  • 13
  • 35
  • 2
    For me the issue was that same field ("dateUpdate") appeared in both operators. I left "dateUpdate" only in $set and solved my problem. – Gediminas Jul 26 '20 at 21:05
3

Starting from MongoDB 4.2 you can use aggregate pipelines in update:

db.your_collection.update({
    _id: 1
}, 
[{
    $set:{
        x_field: {
            $cond: {
                if: {$eq:[{$type:"$_id"} ,  "missing"]},
                then: 'upsert value',   // it's the upsert case
                else: '$x_field'    // it's the update case
            }
        }
    }
}],
{
     upsert: true
})

db.collection.bulkWrite() also supports it

Andrey Hohutkin
  • 2,703
  • 1
  • 16
  • 17
1

With the Ruby library at least, it's possible to get this error if you have the same key twice, once as a symbol and once as a string:

db.getCollection("user").updateOne(
  {_id: ...},
  {$set: {'name': "Horse", name: "Horse"}}
)
hrdwdmrbl
  • 4,814
  • 2
  • 32
  • 41
0

I recently had the same issue while using the query below.

TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.note': req.body.note } }, { upsert: true, new: true })

When i have changed 'content.note' to 'content.$.note' it has been fixed. So my final query is :

TextContainer.findOneAndUpdate({ blockId: req.params.blockId, 'content._id': req.params.noteId }, { $set: { 'content.$.note': req.body.note } }, { upsert: true, new: true })
Enes
  • 323
  • 1
  • 4
  • 11