PaperMC / PaperMC/Paper

Player inventory size oddities

Open
#13,287 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: needs triage version: 1.21.10
Dominant language
Java
Stars
12.7k
Forks
3.5k
Avg merge
3d 13h
Merged PRs (30d)
11

Description

Expected behavior

I expected

var view = player.getOpenInventory();
for (int i = 0; i < view.countSlots(); i++) {
    view.getItem(i);
}

to iterate through all the slots in the player's inventory, including armour slots, the off-hand slot and crafting slots (if the player doesn't have a chest or something open).

Observed/Actual behavior

The above code throws

java.lang.IndexOutOfBoundsException: Index 46 out of bounds for length 46
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) ~[?:?]
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) ~[?:?]
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) ~[?:?]
	at java.base/java.util.Objects.checkIndex(Objects.java:365) ~[?:?]
	at java.base/java.util.ArrayList.get(ArrayList.java:428) ~[?:?]
	at net.minecraft.core.NonNullList.get(NonNullList.java:44) ~[paper-1.21.10.jar:1.21.10-105-1f31ee5]
	at net.minecraft.world.inventory.AbstractContainerMenu.getSlot(AbstractContainerMenu.java:373) ~[paper-1.21.10.jar:1.21.10-105-1f31ee5]
	at org.bukkit.craftbukkit.inventory.CraftInventoryView.getItem(CraftInventoryView.java:73) ~[paper-1.21.10.jar:1.21.10-105-1f31ee5]
Steps/models to reproduce

See the code above.

Plugin and Datapack List

Only the plugin that incorporates a loop similar to the above.

Paper version
Checking version, please wait...
This server is running Paper version 1.21.10-105-main@1f31ee5 (2025-11-04T19:32:20Z) (Implementing API version 1.21.10-R0.1-SNAPSHOT)
You are running the latest version
Previous version: git-Paper-396 (MC: 1.19.3)
Other

It turns out that countSlots() returns 48 in the above case. This number used to be 46, but due to the recent-ish addition of the unused BODY and SADDLE equipment slots to the player inventory, this number is now 48. However, the vanilla player inventory menu doesn't actually incorporate these unused slots, so it still thinks players only have 46 slots.

The method countSlots() adds the sizes of the bottom and top inventories instead of using the backing inventory menu's size, so it outputs 48. On the other hand, getItem(int) in CraftInventoryView directly accesses the backing inventory menu, which then results in the exception.

Possibly CraftInventoryView could override countSlots() to return container.slots.size(), but maybe that will break things in other ways. It's also not ideal that there's a slot discrepancy between views and inventories, but it seems nasty to fix that in the CraftBukkit layer. I'm not sure why those 2 slots aren't part of inventory views/menus anyway.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with CraftInventoryView.countSlots() and getItem(), then compare their use of the backing AbstractContainerMenu and its slots. Reproduce the supplied loop on Paper 1.21.10 and confirm that the reported slot count matches the indices accepted by getItem(), including the player's equipment and crafting slots.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.