You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(db-postgres): restoring version does not clear upload/relationship fields when value is undefined #15976
When restoring a published version that has no upload/relationship field value, the previously draft-saved upload/relationship data persists in the database and is not removed.
Root Cause: In packages/drizzle/src/transform/write/traverseFields.ts, the null check uses strict equality (=== null), which does not catch undefined. When a version is restored and the upload/relationship field was never set, the field value is undefined (not null), so the relationship row is never added to relationshipsToDelete and remains in the database.
Change === null to == null (loose equality) to also catch undefined:
// localizedif(localeData==null){// ✅ catches both null and undefined// non-localized if(fieldData==null||(Array.isArray(fieldData)&&fieldData.length===0)){// ✅
Why undefined occurs
transform/read/traverseFields.ts reads version data — if the upload relationship row doesn't exist in the _rels table, the property is not set on the result object (it becomes undefined, not null)
restoreVersion passes this version data to the write transform
The write transform's traverseFields receives undefined for the field
=== null fails → relationship row is not scheduled for deletion → stale data persists
Link to the code that reproduces this issue
This is a bug in the core library code at packages/drizzle/src/transform/write/traverseFields.ts. The issue can be reproduced with any Payload project using db-postgres (or any drizzle-based adapter) with versioned collections containing upload or relationship fields.
Reproduction Steps
Create a collection with versions: { drafts: true } and an upload field (e.g., image)
Create a document without setting the image → Publish it
Edit the document → Set an image → Save as Draft
Click "Revert to published" (restore the published version that has no image)
Expected: The image field should be empty (matching the published version)
Actual: The image from the draft still appears and is saved to the database
This also affects relationship fields, not just upload fields.
Payload v3: packages/drizzle latest main branch (confirmed same code exists at lines ~551, ~572)
Node.js: v22
PostgreSQL: 15+
Additional Context
We discovered this bug in our production Payload v2 project and confirmed it also exists in v3's packages/drizzle/src/transform/write/traverseFields.ts. We have a working patch for v2 and are happy to submit a PR for v3 as well.
Activity