fix: handle concurrent autosave write conflicts gracefully#16216
Merged
JarrodMFlesch merged 4 commits intoApr 13, 2026
Conversation
…t TypeError and data desync
saveVersion() catches errors during version creation and returns
undefined, which causes two problems:
1. The callers pass undefined as doc to afterRead/afterChange field
hooks, which then throw:
TypeError: Cannot read properties of undefined (reading '_status')
TypeError: Cannot read properties of undefined (reading 'lastPublishedAt')
2. The main document table can update successfully while the version
save silently fails, leaving the document and version history out
of sync.
By re-throwing instead of returning undefined, the entire transaction
is rolled back cleanly when version creation fails. The error is
already logged before the throw, so no diagnostic information is lost.
This is intermittent and primarily surfaces on serverless deployments
(Vercel) where concurrent autosave PATCH requests race within the
same function invocation.
9986861 to
3800a3f
Compare
PatrikKozak
reviewed
Apr 8, 2026
JarrodMFlesch
approved these changes
Apr 10, 2026
JarrodMFlesch
previously requested changes
Apr 10, 2026
JarrodMFlesch
approved these changes
Apr 13, 2026
Contributor
|
🚀 This is included in version v3.83.0 |
milamer
pushed a commit
to milamer/payload
that referenced
this pull request
Apr 20, 2026
…s#16216) ### What? Two-part fix for intermittent 500s during autosave on serverless environments. 1. `updateLatestVersion` catches errors from `updateVersion`/`updateGlobalVersion` and checks whether a concurrent write already succeeded before falling back to `createVersion` 2. `saveVersion` re-throws instead of `return undefined!` so genuine failures still surface as real errors ### Why? On serverless, concurrent autosave requests race to update the same version row. The losing request gets a DB error. Previously `saveVersion` caught it and returned `undefined!`, which was assigned to `result`. Downstream field hooks then accessed properties on `undefined`: ``` TypeError: Cannot read properties of undefined (reading '_status') ``` ### How? When `updateVersion` fails, we re-query the row and check if `updatedAt` has moved — if it has, a concurrent request already committed and we return that result. If not, we fall back to `createVersion`. If that also fails, `saveVersion` re-throws. Fixes payloadcms#16217 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1213985147428664 --------- Co-authored-by: Patrik Kozak <35232443+PatrikKozak@users.noreply.github.com> Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Two-part fix for intermittent 500s during autosave on serverless environments.
updateLatestVersioncatches errors fromupdateVersion/updateGlobalVersionand checks whether a concurrent write already succeeded before falling back tocreateVersionsaveVersionre-throws instead ofreturn undefined!so genuine failures still surface as real errorsWhy?
On serverless, concurrent autosave requests race to update the same version row. The losing request gets a DB error. Previously
saveVersioncaught it and returnedundefined!, which was assigned toresult. Downstream field hooks then accessed properties onundefined:How?
When
updateVersionfails, we re-query the row and check ifupdatedAthas moved — if it has, a concurrent request already committed and we return that result. If not, we fall back tocreateVersion. If that also fails,saveVersionre-throws.Fixes #16217