Skip to content

fix(ui): copy & pasting block content duplicates array items in editor UI#15941

Merged
GermanJablo merged 1 commit intopayloadcms:mainfrom
LeonGatt:issue/copy-and-paste-of-block-fix
Mar 13, 2026
Merged

fix(ui): copy & pasting block content duplicates array items in editor UI#15941
GermanJablo merged 1 commit intopayloadcms:mainfrom
LeonGatt:issue/copy-and-paste-of-block-fix

Conversation

@LeonGatt
Copy link
Copy Markdown
Contributor

What?
When copying a block row that contains an array field and pasting it into a new block of the same type, the array items in the pasted block appeared doubled in the UI (e.g. 3 items → 6 items) immediately after pasting. After saving, the duplicates disappeared since the persisted data was always correct, making this a pure UI state issue.

Why?
When pasting a block row, mergeFormStateFromClipboard intentionally skips .id fields to avoid overwriting the target block's identity. However, the condition clipboardPath.endsWith('.id') was too broad. It skipped all .id paths, including nested array item IDs inside the block (e.g. ctas.0.buttons.0.id).

This left the pasted block's array field with the correct rows metadata (copied from clipboard, containing the source block's IDs), but no corresponding .id form state entries. On the next onChange, the server rebuilt form state from the submitted data, couldn't match any array rows by ID (since the .id fields were missing), and marked all of them as addedByServer: true. When the server response was merged back via mergeServerFormState, those rows were appended to the already-existing client rows doubling them.

How?
Changed the skip condition from matching any .id path to matching only the direct block row ID:

- (!pasteIntoField && clipboardPath.endsWith('.id'))
+ (!pasteIntoField && clipboardPath === ${pathToReplace}.id)
Nested IDs now fall through to the existing ID-regeneration logic, which assigns fresh IDs and updates the rows metadata. The server can then match the rows by their new IDs, so no duplication occurs on merge. The target block's direct ID is still protected from being overwritten.

A unit test was added to mergeFormStateFromClipboard.spec.ts covering the exact scenario.

Fixes #15940

Copy link
Copy Markdown
Contributor

@GermanJablo GermanJablo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really good PR! Thank you so much for the test and the detailed description!

@GermanJablo GermanJablo enabled auto-merge (squash) March 13, 2026 16:38
@GermanJablo GermanJablo merged commit 9bcedc8 into payloadcms:main Mar 13, 2026
155 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🚀 This is included in version v3.79.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copy & Pasting block content duplicates array items in the editor UI

2 participants