Skip to content

Shelf contents changed by anything but a player never update the client display #14192

Description

@RasmusKD

Changing a shelf's contents through anything other than direct player interaction leaves clients rendering the old contents until the chunk is resent. We hit it twice on 26.2: a plugin pulling items out of a shelf through the Bukkit inventory API, and inserting items from console with /item replace block (so the vanilla command path desyncs too).

Reproduce:

  1. Place an oak_shelf and put an item in it so it renders
  2. From console: minecraft:item replace block container.0 with minecraft:air
  3. Server NBT is updated, but the client keeps rendering the item until the chunk reloads

Same result through the API: ((Shelf) block.getState()).getInventory().setItem(0, null).

Cause as far as we can tell: ShelfBlockEntity setItem paths only call setChanged(), while the sendBlockUpdated broadcast only happens in ShelfBlock's player interaction code. Chiseled bookshelves have the sibling problem, their slot occupied blockstate properties never move on API edits.

CraftJukebox.update() already handles exactly this class of problem for jukeboxes, so a similar resync on shelf mutations seems like the natural fix. The workaround plugins use today is a fresh getState().update(true, false) after every mutation, which costs a state creation per edit.

Found while working on CraftBook's shelf support (EngineHub/CraftBook#1376). Written with AI assistance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions