Skip to content

PlayerInventorySlotChangeEvent#getSlot() returns misleading slot when armor changes while another inventory is open` #13991

Description

@PQguanfang

Expected behavior

PlayerInventorySlotChangeEvent#getSlot() and PlayerInventorySlotChangeEvent#getRawSlot() should reliably identify the changed slot in the player's own inventory, especially for armor/offhand slots.

Observed/Actual behavior

When a player has another inventory view open, for example a chest, and an armor slot changes due to external causes, such as a zombie attacking the player and damaging armor durability, PlayerInventorySlotChangeEvent is fired, but the slot values appear incorrect or misleading.

In this case:

  • event.getRawSlot() does not behave as expected for the currently changed player inventory slot.
  • event.getSlot() appears to be converted using the currently open InventoryView.
  • Because the player is viewing a chest, event.getSlot() may map to a slot in the chest view instead of representing the actual armor slot that changed.

This makes it difficult or impossible for plugins to safely detect armor slot changes using this event while the player has another container open.

Steps/models to reproduce

  1. Create a plugin that listens to PlayerInventorySlotChangeEvent.
  2. Log the following values:
    • event.getRawSlot()
    • event.getSlot()
    • event.getOldItemStack()
    • event.getNewItemStack()
    • player.getOpenInventory().getType()
  3. Equip armor on the player.
  4. Open a chest.
  5. Let a zombie attack the player so that the armor durability changes.
  6. Observe the logged slot values.

Plugin and Datapack List

None except for a test plugin, source code:
Example listener:

@EventHandler
public void onSlotChange(PlayerInventorySlotChangeEvent event) {
    Player player = event.getPlayer();

    player.sendMessage("Open view: " + player.getOpenInventory().getType());
    player.sendMessage("Raw slot: " + event.getRawSlot());
    player.sendMessage("Slot: " + event.getSlot());
    player.sendMessage("Old item: " + event.getOldItemStack());
    player.sendMessage("New item: " + event.getNewItemStack());
}

Paper version

This server is running Paper version 26.1.2-69-main@76d2ac7 (2026-06-03T17:32:02Z) (Implementing API version 26.1.2.build.69-stable)

Other

If this is an unsolvable problem or work as excepted, it should at least be ensured that the PlayerInventorySlot ChangeEvent is not triggered in this situation, otherwise the plugin will listen for incorrect slot values in this situation, causing various chain problems.

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions