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

Internal server error on set followed by unset #1798

Open
4 tasks done
mstniy opened this issue Nov 2, 2022 · 12 comments · May be fixed by #2117
Open
4 tasks done

Internal server error on set followed by unset #1798

mstniy opened this issue Nov 2, 2022 · 12 comments · May be fixed by #2117
Labels
bounty:$20 Bounty applies for fixing this issue (Parse Bounty Program) type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@mstniy
Copy link
Contributor

mstniy commented Nov 2, 2022

New Issue Checklist

Issue Description

Setting a subdocument entirely, followed by an unset of a nested field causes an internal server error while the object is being saved, if the object existed beforehand.

Steps to reproduce

const myObj = new Parse.Object('MyClass');
await myObj.save(null, {useMasterKey: true});
myObj.set('data', {a: 5});
myObj.unset('data.a');
await myObj.save(null, {useMasterKey: true});
console.log('a');

Actual Outcome

error: Uncaught internal server error. Updating the path 'data.a' would create a conflict at 'data' {"code":40,"codeName":"ConflictingUpdateOperators","ok":0,"stack":"MongoServerError: Updating the path 'data.a' would create a conflict at 'data'\n    at Connection.onMessage (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/connection.js:202:30)\n    at MessageStream.<anonymous> (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/connection.js:62:60)\n    at MessageStream.emit (events.js:400:28)\n    at processIncomingData (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/message_stream.js:108:16)\n    at MessageStream._write (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/message_stream.js:28:9)\n    at writeOrBuffer (internal/streams/writable.js:358:12)\n    at MessageStream.Writable.write (internal/streams/writable.js:303:10)\n    at Socket.ondata (internal/streams/readable.js:731:22)\n    at Socket.emit (events.js:400:28)\n    at addChunk (internal/streams/readable.js:293:12)"}
MongoServerError: Updating the path 'data.a' would create a conflict at 'data'
    at Connection.onMessage (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/connection.js:202:30)
    at MessageStream.<anonymous> (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/connection.js:62:60)
    at MessageStream.emit (events.js:400:28)
    at processIncomingData (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/message_stream.js:108:16)
    at MessageStream._write (/home/kartal/Desktop/ocell/parse-server-example/node_modules/parse-server/node_modules/mongodb/lib/cmap/message_stream.js:28:9)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at MessageStream.Writable.write (internal/streams/writable.js:303:10)
    at Socket.ondata (internal/streams/readable.js:731:22)
    at Socket.emit (events.js:400:28)
    at addChunk (internal/streams/readable.js:293:12)

Expected Outcome

The object should be saved to the database with data = {}

Environment

Server

  • Parse Server version: 5.3.0
  • Operating system: ubuntu 20.04
  • Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): local

Database

  • System (MongoDB or Postgres): MongoDB
  • Database version: 5.0.13
  • Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc): local

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): parse dashboard
  • SDK version: 4.1.4

Logs

@parse-github-assistant
Copy link

parse-github-assistant bot commented Nov 2, 2022

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

@mtrezza mtrezza added type:bug Impaired feature or lacking behavior that is likely assumed bounty:$20 Bounty applies for fixing this issue (Parse Bounty Program) labels Nov 2, 2022
@mtrezza
Copy link
Member

mtrezza commented Nov 2, 2022

Nice find! Do you want to open a PR? This may well be a Parse JS SDK issue rather than a Parse Server issue, if the SDK doesn't handle this set / unset properly. Did you look at what the SDK sends to the server?

@mstniy
Copy link
Contributor Author

mstniy commented Nov 9, 2022

I have verified that the SDK sends a malformed request to the server, so this is an SDK issue.

@mtrezza
Copy link
Member

mtrezza commented Nov 9, 2022

Great, would you want to open a PR with a failing test?

@mtrezza
Copy link
Member

mtrezza commented Mar 1, 2023

@mstniy Do you have any more infos on this issue? Otherwise I'll transfer it to the Parse JS SDK.

@mstniy
Copy link
Contributor Author

mstniy commented Mar 1, 2023

I am afraid not, @mtrezza . Feel free to transfer the issue. We ended up working around it.

@parse-github-assistant
Copy link

parse-github-assistant bot commented Mar 1, 2023

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

@mtrezza mtrezza transferred this issue from parse-community/parse-server Mar 1, 2023
@mortenmo
Copy link
Contributor

Looking at this for a moment, not sure there isn't more related issues.

Trying to just add data.b (not unsetting) and trying to get it after removes locally the previous value. It doesn't merge the ops locally.

Screenshot 2024-04-17 at 9 07 51 PM

I didn't realize dot notation was even supported on set/get, but there seem to be a lot of issues with it.

@harshbhar0629
Copy link

Steps to reproduce
const myObj = new Parse.Object('MyClass');
await myObj.save(null, {useMasterKey: true});
myObj.set('data', {a: 5});
myObj.unset('data.a');
await myObj.save(null, {useMasterKey: true});
console.log('a');

Above code gives internal server error because of conflict.

MY Solution:
The error you're encountering is due to conflicting update operations in MongoDB. Specifically, you're trying to unset a nested field (data.a) after modifying the object, which is causing MongoDB to throw the ConflictingUpdateOperators error because it doesn't allow multiple operations that affect the same path in a single update.

Here's how you can resolve it:

Solution 1: Use Separate Saves
Instead of updating and unsetting in the same save operation, separate them into distinct saves to avoid conflicting update operators.

conflictingSol1

Explanation
Initial Save: The object is first saved with no changes.
Set and Save: The object’s data field is set with the value { a: 5 } and saved.
Unset and Save: The nested field data.a is then unset and saved again in a separate operation.

@mtrezza Please review it once:)

@mtrezza
Copy link
Member

mtrezza commented Oct 8, 2024

Specifically, you're trying to unset a nested field (data.a) after modifying the object, which is causing MongoDB to throw the ConflictingUpdateOperators error because it doesn't allow multiple operations that affect the same path in a single update.

@harshbhar0629 Good analysis, I think we may have 2 issues here:

  1. If the MongoDB driver returns an error, like ConflictingUpdateOperators, then the server should not have an internal error, but the error should be caught, logged with details, and a general Parse Error should be returned, without any specific internal error details for security reasons.
  2. Given your code example above, there seems to be an issue in how we handle set-unset combinations to form the DB request.

Would you want to write a fix? You could start with a PR that contains the code example you posted above to demonstrate the issue.

@harshbhar0629
Copy link

I will try to fix that issue Sir:)

@mtrezza
Copy link
Member

mtrezza commented Oct 8, 2024

@harshbhar0629 I didn't notice but we already have an open PR with #2117. Please see the discussion there and feel free to pick up from there, as the PR seems to have gone stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bounty:$20 Bounty applies for fixing this issue (Parse Bounty Program) type:bug Impaired feature or lacking behavior that is likely assumed
Projects
None yet
4 participants