Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating the path 'x' would create a conflict at 'x' #10646

Closed
simllll opened this issue Aug 31, 2021 · 15 comments
Closed

Updating the path 'x' would create a conflict at 'x' #10646

simllll opened this issue Aug 31, 2021 · 15 comments
Milestone

Comments

@simllll
Copy link
Contributor

simllll commented Aug 31, 2021

Do you want to request a feature or report a bug?
bug

What is the current behavior?
mongoose throws an error when executing following query, when executed with

const result = await this.jobAlarmModel
.findOneAndUpdate(query, update, {
returnDocument: 'after',
upsert: true
})
.lean()
.exec();
QUERY {
   "targets": {
      "$elemMatch": {
         "type": "user",
         "params": "58d1310c6162444627d0431e" // ObjectId
      }
   },
   "subscriptions._id": "612e07ec24dd373ff6ed7f53" // ObjectId
}
update {
   "$unset": {
      "deactivated": true
   },
   "$setOnInsert": {
      "interval": 12,
      "lastCheck": "2021-08-31T11:12:32.635Z",
      "targets": [
         {
            "type": "user",
            "params": "58d1310c6162444627d0431e" // ObjectId
         }
      ]
   },
   "$set": {
      "subscriptions.$": {
         "search": {
            "region": "AT",
            "filters": [],
            "_location": "57feb684ebca08c825327731",
            "locationCoords": {
               "lon": 16.374,
               "lat": 48.208
            },
            "_field": [
               "55d05b8c315478e647148bea",
               "55d06b4c347584e641746bea",
               "55d14b9c378694e682645bea",
               "55d20b2c362610e685346bea",
               "55d21b3c390229e676643bea",
               "55d25b2c316398e653743bea",
               "55d27b6c394742e606746bea",
               "55d31b1c365318e683848bea",
               "55d52b3c347314e611042bea",
               "55d56b7c310848e678649bea",
               "55d58b1c377013e659243bea",
               "55d59b7c347254e692244bea",
               "55d6389d365315e629446c08",
               "55d638ae365315e629446c09",
               "55d638f4365315e629446c0a",
               "55d6391c365315e629446c0c",
               "55d63b68365315e629446c16",
               "55d66b5c319117e666745bea",
               "55d78b1c322056e639043bea",
               "55d81b8c304579e699343bea",
               "55d84b5c308150e679540bea",
               "55d88b8c326897e669748bea",
               "55d97b5c372222e635748bea",
               "55d98b6c305015e673045bea",
               "569e8adb1142e6fb6f096887",
               "569e8aea1142e6fb6f096888",
               "569e8b021142e6fb6f09688b",
               "569e8b0b1142e6fb6f09688c",
               "56b35442b5c5f2a71436dc56",
               "56b3544db5c5f2a71436dc57",
               "56b35456b5c5f2a71436dc58"
            ]
         },
         "lastResult": "2021-08-31T11:12:32.635Z",
         "lastView": "2021-08-31T11:12:32.635Z",
         "createdAt": "2021-08-31T11:12:32.635Z",
         "_id": "612e07ec24dd373ff6ed7f53" // ObjectId
      }
   }
}

throws

MongoServerError: Updating the path 'subscriptions' would create a conflict at 'subscriptions'
   at MessageStream.messageHandler (/home/simon/Dev/hokify/hokify-server/node_modules/mongodb/src/cmap/connection.ts:740:20)
   at MessageStream.emit (node:events:394:28)
   at MessageStream.emit (node:domain:475:12)
   at processIncomingData (/home/simon/Dev/hokify/hokify-server/node_modules/mongodb/src/cmap/message_stream.ts:167:12)
   at MessageStream._write (/home/simon/Dev/hokify/hokify-server/node_modules/mongodb/src/cmap/message_stream.ts:64:5)
   at writeOrBuffer (node:internal/streams/writable:389:12)
   at _write (node:internal/streams/writable:330:10)
   at MessageStream.Writable.write (node:internal/streams/writable:334:10)
   at Socket.ondata (node:internal/streams/readable:754:22)
   at Socket.emit (node:events:394:28)
   at Socket.emit (node:domain:475:12)
   at addChunk (node:internal/streams/readable:315:12)
   at readableAddChunk (node:internal/streams/readable:289:9)
   at Socket.Readable.push (node:internal/streams/readable:228:10)
   at TCP.onStreamRead (node:internal/stream_base_commons:199:23)
   at TCP.callbackTrampoline (node:internal/async_hooks:130:17) {
 ok: 0,
 code: 40,
 codeName: 'ConflictingUpdateOperators',
 operationTime: new Timestamp({ t: 1630408352, i: 257 }),
 '$clusterTime': {
   clusterTime: new Timestamp({ t: 1630408352, i: 257 }),
   signature: {
     hash: new Binary(Buffer.from("b082c2eec59a4c328f73ac552f65029e2bb0b39a", "hex"), 0),
     keyId: new Long("6963739298038284312")
   }
 }
}

but calling it with the native collection, it works:

const result = await this.jobAlarmModel
	.collection
	.findOneAndUpdate(query, update, {
		returnDocument: 'after',
		upsert: true
	});

=> no error at all.

{
  lastErrorObject: { n: 1, updatedExisting: true },
  value: {
    _id: new ObjectId("612e07ec24dd373ff6ed7f54"),
    __v: 0,
    createdAt: 2021-08-31T10:43:56.378Z,
    interval: 12,
    lastCheck: 2021-08-31T10:43:56.373Z,
    subscriptions: [ [Object] ],
    targets: [ [Object] ],
    updatedAt: 2021-08-31T10:43:56.378Z
  },
  ok: 1,
  operationTime: new Timestamp({ t: 1630408283, i: 22 }),
  '$clusterTime': {
    clusterTime: new Timestamp({ t: 1630408283, i: 22 }),
    signature: {
      hash: new Binary(Buffer.from("87cdc921cb1ad264b0e8858ffbcb9c7722b1c00e", "hex"), 0),
      keyId: new Long("6963739298038284312")
    }
  }
}

it seems mongoose does some "bad" magic with the query ;).
Works with mongosoe 5.x, but not with mongoose 6.x

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
mongoose 6.0.3
node v16.7.0
mongodb 4.4.1

@simllll
Copy link
Contributor Author

simllll commented Aug 31, 2021

I have the feeling that somehow an already converted object id, is converted again to an object id, and this somehow results into loosing the value of the id. Is it possible that there is a check missing if the "id" is already a typeof Types.ObjectId?

@IslandRhythms IslandRhythms added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Sep 1, 2021
@IslandRhythms
Copy link
Collaborator

Please include your connection code.

@vkarpov15
Copy link
Collaborator

Likely a duplicate of #10624, upgrade to v6.0.4 and it should go away.

If not, let me know, but set setDefaultsOnInsert: false on your update options and that should fix the issue 👍

@simllll
Copy link
Contributor Author

simllll commented Sep 1, 2021

Sounds very similar, thanks for the hint. I will test it tomorrow and let you know! Thanks!

@simllll
Copy link
Contributor Author

simllll commented Sep 2, 2021

I just tested it, it works now! Thanks!

But one final question, the model has defaults of "undefined" to ensure that there is no array created. We have this in several places, e.g.
_field: { type: [{ type: Schema.Types.ObjectId, ref: 'JobField' }], default: undefined },

filters: {
type: [String],
default: undefined
}

would it be better to just use "setDefaultsOnInsert: false" instead..? the most common use case for default values on our side, is that we set them to undefined that mongoose does no special magic on it. Or is there even an option that there is only a default created if default value is explciity set to an value and disbale the "auto create array" behaviour?

Thanks again!

@simllll simllll closed this as completed Sep 2, 2021
@vkarpov15
Copy link
Collaborator

I'll take a look re: the undefined defaults, setDefaultsOnInsert should ignore undefined defaults.

@vkarpov15 vkarpov15 reopened this Sep 3, 2021
@vkarpov15 vkarpov15 added this to the 6.0.6 milestone Sep 3, 2021
@vkarpov15 vkarpov15 removed the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Sep 3, 2021
@vkarpov15 vkarpov15 modified the milestones: 6.0.6, 6.0.5 Sep 4, 2021
@vkarpov15
Copy link
Collaborator

@simllll I took a closer look and can confirm that Mongoose does not add undefined defaults to setOnInsert, the below script:

'use strict';
  
const mongoose = require('mongoose');

mongoose.set('debug', true);

run().catch(err => console.log(err));

async function run() {
  console.log(`Mongoose version: ${mongoose.version}`);
  await mongoose.connect('mongodb://localhost:27017/test');
  await mongoose.connection.dropDatabase();
  
  const schema = new mongoose.Schema({
    name: String,
    tags: { type: [String], default: undefined }
  });
  
  const Test = mongoose.model('Test', schema);

  await Test.updateOne({}, { name: 'test' }, { upsert: true });
  console.log('Done');
} 

Outputs:

$ node gh-10646.js 
Mongoose version: 6.0.4
Mongoose: tests.updateOne({}, { '$setOnInsert': { __v: 0 }, '$set': { name: 'test' } }, { upsert: true })
Done

So you don't need to disable setDefaultsOnInsert on account of default: undefined on your arrays.

@simllll
Copy link
Contributor Author

simllll commented Sep 4, 2021

Interesting, is this since the last update or should it be like this already in earlier versions? The thing is I got this problems with a model that only had default undefined definitions.

@vkarpov15
Copy link
Collaborator

We made some fixes related to setDefaultsOnInsert in 6.0.4 with #10624, so it may be only since the latest release.

@hardcodet
Copy link

I'm running into this one since I upgraded to 6.x (6.0.11) today - this one seems to have show stopper quality :/
Let me know if I can provide context that is helpful here, or if this is already fixed in DEV by #10677 @vkarpov15

@hardcodet
Copy link

Backporting to 6.0.3 seems to resolve the issue for me.

@vkarpov15
Copy link
Collaborator

@hardcodet can you please open a new issue and follow the issue template?

@chemdrew
Copy link

chemdrew commented Jun 7, 2022

this seems to have popped back up in v6.3.X, had to downgrade to 6.1.10 to prevent the error

@azjgard
Copy link

azjgard commented Jun 8, 2022

Ran into this problem on v6.3.6 as part of upgrading from v5; as also noted by @chemdrew, downgrading to v6.1.10 fixes the issue.

@katusiky
Copy link

This problem occurs when use findOneAndUpdate with the upsert flag as true and try update a property which already have default option in schema. To solve this, addsetDefaultsOnInsert: false on query options.

it should be something like this: { upsert: true, setDefaultsOnInsert: false }

@Automattic Automattic locked as resolved and limited conversation to collaborators Jun 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants