payloadcms / payloadcms/payload
cloneDataFromOriginalDoc mangles json array-of-arrays into index-keyed objects on partial update
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
On a partial payload.update / REST PATCH that omits a json field, cloneDataFromOriginalDoc (dist/fields/hooks/beforeChange/cloneDataFromOriginalDoc.js) shallow-clones each array row with {...row}. When the stored value is an array of arrays (e.g. [[lng, lat], ...] coordinate tuples), every inner array is spread into an index-keyed object {"0": lng, "1": lat}.
On a publish operation this trips the field's validate, but draft saves skip validation, so the corrupted shape persists to the database. Downstream consumers that iterate the tuples then crash with TypeError: object is not iterable.
Link to the code that reproduces this issue
n/a (minimal repro below)
Reproduction Steps
- Define a collection with a
jsonfield, drafts enabled. - Save a document whose
jsonvalue is an array of arrays, e.g.[[1, 2], [3, 4]]. - Run a partial update that omits the json field:
await payload.update({ collection: 'things', id, data: { someOtherField: 'x' }, // json field NOT included draft: true, }) - Read the stored value — it is now
[{ "0": 1, "1": 2 }, { "0": 3, "1": 4 }]instead of[[1, 2], [3, 4]].
Element order is preserved (so it is recoverable), but the nested arrays are gone.
Expected
Nested arrays inside a json value should be preserved verbatim when the field is omitted from a partial update. A shallow {...row} clone should not be applied to array rows — a structured/deep clone would retain the original shape.
Environment
- Payload: 3.85.1
- Database: @payloadcms/db-postgres (json column)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in dist/fields/hooks/beforeChange/cloneDataFromOriginalDoc.js and reproduce the partial payload.update or REST PATCH that omits the json field. Verify that array-of-arrays values retain their nested array shape after draft saves, and add regression coverage for the [[1, 2], [3, 4]] example so the stored value is unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, typescript
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100