Skip to content

moveBlockToPosition can cause deletion of the last top-level block in Editor #75720

@kadamwhite

Description

@kadamwhite

Description

If you call moveBlockToPosition() with the clientId of a nested block and the incorrect fromRootClientId of '', it will delete the last top-level block in the document instead of moving the target block.

We were a bit surprised when we hit this on a client site, when code that was intended to "pin" a block to the top after insertion repeatedly triggered and ended up deleting the entire post's content.

Step-by-step reproduction instructions

In a blank block editor post, run the following snippet in console to create a hierarchy of groups with paragraph blocks inside them:

const groups = [
    wp.blocks.createBlock( 'core/group', {}, [
        wp.blocks.createBlock( 'core/paragraph', { content: 'Par 1' } ),
    ] ),
    wp.blocks.createBlock( 'core/group', {}, [
        wp.blocks.createBlock( 'core/paragraph', { content: 'Par 2' } ),
    ] ),
    wp.blocks.createBlock( 'core/group', {}, [
        wp.blocks.createBlock( 'core/paragraph', { content: 'Par 3' } ),
    ] ),
];

wp.data.dispatch( 'core/block-editor' ).insertBlocks( groups );

Then, run this snippet to try to move the paragraph out from the last group and into the first position in the editor:

wp.data.dispatch('core/block-editor').moveBlockToPosition(
    groups[2].innerBlocks[0].clientId,
    '', // fromRootClientId
    '', // toRootClientId -- want to move to top-level
    0 // targetPosition -- can be any index
);

Expected

  • either nothing would happen since the fromRootClientId is incorrect,
  • or the block moves to the start as intended
  • and at minimum no unrelated blocks would be deleted either way

Actual

  • The last group in the post is deleted
  • If the dispatch is repeated two more times, the other groups are deleted, even though our target block (Par 3) isn't even in the editor's hierarchy anymore
  • If you run this code snippet on a post which already has content, you can repeat the dispatch until the post is entirely empty

Screenshots, screen recording, code snippet

Image

Environment info

  • WordPress 6.9.1, stock Gutenberg
  • Tested in Chrome and Firefox on macOS 15.7.3, but observed on Windows as well
  • Also replicated in the Playground

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Metadata

Metadata

Assignees

Labels

[Package] Block editor/packages/block-editor[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions