AfterChange hook bug in Mongodb Atlas: fails updating the same document
Closed this issue · 3 comments
Describe the Bug
I am trying to use an afterChange hook to update the same document, but it fails with Caused by :: Write conflict during plan execution and yielding is disabled. :: Please retry your operation or multi-document transaction.
I am using the MongoDB Atlas free Tier to host my database. It is currently on version 8.0.13
This used to be working just fine in the past, and for some reason no longer works but we haven't been able to pinpoint the exact reason. We have tried bisecting the issue around our last changes but have not found the culprit in our own changes.
Our investigation
We noticed that currently only our acceptance database experiences this issue, while our production database is still OK. The difference between the two is that our acceptance database is a Free Tier, while the production database is Serverless. Also good to note is that MongoDB Atlas has been performing changes to their Tiers, and moved our acceptance cluster from Serverless to "Free Tier"; we believe this may be related.
We tried disabling transactions in payload's mongodb configuration with transactionOptions: false and while we do see some strange loading behavior with a stuck "submitting" toast, it does seem to work and successfully change the document. However we actually want transactions in order to have atomic behavior.
This also works perfectly fine locally using a mongodb docker image, so it points towards some interaction between the settings of payload & MongoDB Atlas -- specifically their Free Tier, probably related to transactions.
Some context about our use-case
For your information; the reasons we are using an afterChange hook to save to the same document is to perform some size calculations based on the contents of a document (the size of the document, its related media uploads, etc). We also considered using the beforeChange hook, but the docs mention the data should be treated as unvalidated user input, which does not fit our use-case, and we also want images to be upload to our S3 buckets prior to this computation.
Link to the code that reproduces this issue
https://github.com/sacha-c/payload/tree/reproduction/mongodb-atlas-afterChange-hook
Reproduction Steps
- Set up a Free Tier cluster in MongoDB Atlas: cloud.mongodb.com
- Install the
@payloadcms/db-mongodbpackage - Add the connection string to the reproduction repo
- Modify the existing Post's title
- See that the error appears
Which area(s) are affected? (Select all that apply)
db-mongodb
Environment Info
payload: 3.54.0
node.js: v23.11.0
next.js: 15.4.4
mongodb: 8.0.13
Hi @sacha-c,
This is a common issue. In your reproduction I see it does not have req. You will want to pass in the req from the hook's args to the local API request, this will allow the DB operation to be called using the same db transaction as the original create/update being performed.
await req.payload.update({
collection: 'posts',
req, // add this line to any local API calls you have.
id: doc.id,
data: {
title: 'I would like to be updated',
},
})See documentation: https://payloadcms.com/docs/local-api/overview#transactions
Let me know if I'm missing something but I believe this is the case.
Great, it works! Thank you, I did miss this in the documentation.
Still a little strange that this issue does not happen consistently (using a local docker image & MongoDB Serverless it doesn't throw), I suppose somehow transactions just don't work there and the error is silenced or something
But in any case this does seem to solve the issue we had for MongoDB Free Tier, so we can continue working 👍
This issue has been automatically locked.
Please open a new issue if this issue persists with any additional detail.