[SPIGOT-3020] Exception when set item in main hand to AIR on PlayerInteractEvent Created: 18/Jan/17  Updated: 09/Aug/20  Resolved: 09/Aug/20

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Denis Abramov Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None

Attachments: PNG File Screen Shot 2020-08-07 at 8.14.39 PM.png    
Issue Links:
Duplicate
is duplicated by SPIGOT-5444 Removing item in hand crashes server Resolved
is duplicated by SPIGOT-6048 When I try to remove items from playe... Resolved

 Description   
Error executing task
java.util.concurrent.ExecutionException: java.lang.AssertionError: TRAP
at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_111]

at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_111]
at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:47) [server.ja
r:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:
739) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:
399) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:
675) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.jav
a:574) [server.jar:git-Spigot-7d78b81-f709362]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_111]
Caused by: java.lang.AssertionError: TRAP
at net.minecraft.server.v1_11_R1.ItemStack.F(ItemStack.java:94) ~[server
.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.ItemStack.setCount(ItemStack.java:822)
~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerInteractManager.a(PlayerInteractM
anager.java:403) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.jav
a:957) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PacketPlayInBlockPlace.a(PacketPlayInBl
ockPlace.java:26) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PacketPlayInBlockPlace.a(PacketPlayInBl
ockPlace.java:1) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:
13) ~[server.jar:git-Spigot-7d78b81-f709362]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~
[?:1.8.0_111]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_111]
at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) ~[server.j
ar:git-Spigot-7d78b81-f709362]
... 5 more

This exception throws when I'm setting to AIR item in player's hand on PlayerInteractEvent with right click.



 Comments   
Comment by Shane Bee [ 08/Aug/20 ]

Okay doing a little more digging, here is what I found (numbers correlate to image):
Player places a block
1) Block place event is called
2) Plugin changes the player's tool to AIR/NULL
3) Minecraft doesn't know about this change, therefor tries to remove 1 from the ItemStack

Would a possible solution here be something like so:

if (itemstack != null && itemstack != ItemStack.b) {
    itemstack.subtract(1);
}

Thus only subtracting from the ItemStack if its not null.

Comment by Shane Bee [ 08/Aug/20 ]

I see your point.
The sad thing here is simply using a BlockPlaceEvent -> setting the player's tool to AIR, causes the server to crash.
Unless I am crazy, within my testing using a try/catch still causes the crash.

Understandably cancelling the event first is the smart thing to do, but in general, using a simple line of the Bukkit API realistically shouldn't cause the server to crash.

On that note, many of our Skript users do silly things like this too, simply using a block break event and setting the tool to AIR, therefor crashing the server. We've been trying to find a way to "patch" this by adding a 1 tick delay when they set the tool, unfortunately this could cause other issues across the board, so in turn we are telling them to handle it themselves by adding a delay and/or cancelling the event first.

The problem here is adding a 1 tick delay, could potentially cause issues with duping and the like.

Maybe, possibly, the block place event cant be reorganized to prevent this error/crash?

Comment by md_5 [ 08/Aug/20 ]

The line is to detect modifications to the 'null' ItemStack.b stack which is meant to be immutable and represent air. Without it bad code (ie this code) ends up modifying the null stack which is obviously not desired and could lead to strange comparison behaviour all over the server. Removing it is in my view akin to just surrounding erroring code with an empty catch block.

Comment by Shane Bee [ 08/Aug/20 ]

So I know the error is caused by this line:
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/nms-patches/ItemStack.patch#52

For poops and haha's I removed the line, and the server does not crash, and code works as intended.

Im now wondering, what exactly is the importance of this line?
And if its causing crashes, why is it still there?

Comment by Oliver Maenen [ 15/Apr/20 ]

You're welcome. Oh, damn, I didn't even try the difference between creative and survival mode.
As for the exploit, yeah, you might need to be careful for that, in my case dropping it doesn't work since I open a menu instantly an hitting the drop key just closes the menu but you should indeed be careful for that.
Either way that's still better than crashing the server in my opinion
Good luck!

Comment by Nathan Wolf [ 15/Apr/20 ]

Thank you for the work-around! I may have to try that.

I get a bug report about once or twice a week around this. My plugin, for instance, has custom consumables- you right-click to consume it, crashes the server if you do it in creative mode. It's pretty frustrating, at this point I just put up a big "this plugin is not compatible with creative mode" disclaimer in as many places as I can, but of course people never read those.

I might try adding the delay if it's something I can do without being exploitable (e.g. can a player right-click and hit the drop key to consume and keep the item? Probably...)

Comment by Oliver Maenen [ 15/Apr/20 ]

This doesn't only happen when setting to AIR. a simple inventory.remove(itemStack) will also cause it to crash, however only in this circumstance:
The command is run on a (right click) interact event with the item that needs to be removed in hand. I also read somewhere that the item needs to be a tool (like a pickaxe) but I didn't test it with other items, so I'm not sure.

Somehow there's a strange connection between these 2 or 3 conditions, it causes a complete server crash.
I worked my way around this bug by adding a 1 tick delay to the removal of the item, it fixes the issue and no longer crashes the server.
Hope this helps, @md_5. 

Comment by Loggits [ 26/Feb/20 ]

I was able to reproduce this using:

@EventHandler
public void onDispense (BlockDispenseEvent event) {
    event.setItem(new ItemStack(Material.AIR));
}

I was trying to remove the item without cancelling, to modify shulker behaviour and noticed the error.

Description: Exception while tickingDescription: Exception while ticking
java.lang.AssertionError: TRAP at net.minecraft.server.v1_15_R1.ItemStack.checkEmpty(ItemStack.java:114) at net.minecraft.server.v1_15_R1.ItemStack.setCount(ItemStack.java:911) at net.minecraft.server.v1_15_R1.ItemStack.cloneAndSubtract(ItemStack.java:160) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.a(DispenseBehaviorItem.java:25) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.dispense(DispenseBehaviorItem.java:15) at net.minecraft.server.v1_15_R1.DispenseBehaviorShulkerBox.a(DispenseBehaviorShulkerBox.java:40) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.dispense(DispenseBehaviorItem.java:15) at net.minecraft.server.v1_15_R1.BlockDispenser.dispense(BlockDispenser.java:63) at net.minecraft.server.v1_15_R1.BlockDispenser.tick(BlockDispenser.java:89) at net.minecraft.server.v1_15_R1.IBlockData.a(IBlockData.java:206) at net.minecraft.server.v1_15_R1.WorldServer.b(WorldServer.java:707) at net.minecraft.server.v1_15_R1.TickListServer.b(TickListServer.java:90) at net.minecraft.server.v1_15_R1.WorldServer.doTick(WorldServer.java:411) at net.minecraft.server.v1_15_R1.MinecraftServer.b(MinecraftServer.java:1245) at net.minecraft.server.v1_15_R1.DedicatedServer.b(DedicatedServer.java:430) at net.minecraft.server.v1_15_R1.MinecraftServer.a(MinecraftServer.java:1112) at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:934) at java.base/java.lang.Thread.run(Thread.java:832)
-- Head ---- Head --Thread: Server threadStacktrace: at net.minecraft.server.v1_15_R1.ItemStack.checkEmpty(ItemStack.java:114) at net.minecraft.server.v1_15_R1.ItemStack.setCount(ItemStack.java:911) at net.minecraft.server.v1_15_R1.ItemStack.cloneAndSubtract(ItemStack.java:160) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.a(DispenseBehaviorItem.java:25) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.dispense(DispenseBehaviorItem.java:15) at net.minecraft.server.v1_15_R1.DispenseBehaviorShulkerBox.a(DispenseBehaviorShulkerBox.java:40) at net.minecraft.server.v1_15_R1.DispenseBehaviorItem.dispense(DispenseBehaviorItem.java:15) at net.minecraft.server.v1_15_R1.BlockDispenser.dispense(BlockDispenser.java:63) at net.minecraft.server.v1_15_R1.BlockDispenser.tick(BlockDispenser.java:89) at net.minecraft.server.v1_15_R1.IBlockData.a(IBlockData.java:206) at net.minecraft.server.v1_15_R1.WorldServer.b(WorldServer.java:707)
Comment by Nathan Wolf [ 08/May/18 ]

@md_5 sorry for the ping (er.. maybe ping... is this thing on?), I wasn't sure if closed issues were on your radar, but I didn't want to open yet another duplicate of this issue.

I'd love to hear if you have further thoughts on this, it is extremely reproducible with the right setup. Thanks!

 

EDIT: Yeah don't think that's actually pinging you anyway ... 

Comment by Nathan Wolf [ 30/Apr/18 ]

I can reproduce this also.

FYI this duplicates SPIGOT-2977 and SPIGOT-2874.

Minimum code to reproduce would look like this:

@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
    Player player = event.getPlayer();
    player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
}

Reproduction steps:

  1. Be in creative mode
  2. Be looking up in the air (not at a block)
  3. Right-click with an item, where some plugin will remove that item on right-click

I have a simple reproduction plugin here:

https://github.com/NathanWolf/Bukkit-Unit-Tests/releases/tag/soup-1.0

Source: https://github.com/NathanWolf/Bukkit-Unit-Tests/tree/creative-consume

I tried to trace the code, but I'm not certain how it's getting to this assertion.

In PlayerConnection.a(PacketPlayInBlockPlace) there is an "if (!itemstack.isEmpty()) {" check that seems like it should short-circuit the logic, but I guess it must trigger prior to my plugin removing the item.

But then, oddly, in PlayerInteractManager.a(HumanEntity, World, ItemStack, EnumHand) it does ItemStack.getCount() and gets 0 back. So how was that not an empty item?

The error then occurs trying to set the ItemStack's count to 0, in a creative-mode-only logic block.

I considered submitting a work-around PR to just avoid the setCount if count is zero, but that felt like a band-aid.

If I can reach understanding of the true root cause I will PR, but I'm not sure how likely that is. I'm hoping you can help with a work-around or a real fix, though delaying removal of the item by one tick is probably not an acceptable solution for exploit reasons.

For what it's worth, I have tried setting the item in hand to air and null, both have the same effect.

Currently testing on 

git-Spigot-2086bb0-21d5f75

.. which I see is now one version behind, I will test on latest and report back if there is a change, but I doubt the Netty version bump would affect this.

Comment by Denis Abramov [ 19/Jan/17 ]

I've reproduced it on two different machines running latest(git-Spigot-0b1090d-7fdc749) version of Spigot.

Comment by md_5 [ 19/Jan/17 ]

Still cannot reproduce.

Comment by Denis Abramov [ 19/Jan/17 ]

Exception causes only when player in CREATIVE mode after right click with any item in main hand.

@EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
   if(e.getHand() == EquipmentSlot.HAND) {
     e.getPlayer().getInventory().setItemInMainHand(new ItemStack(Material.AIR));
   }
}
Comment by md_5 [ 18/Jan/17 ]

Make sure your server is up to date; Include code and exact reproduction steps.

Comment by Denis Abramov [ 18/Jan/17 ]
Error executing task
java.util.concurrent.ExecutionException: java.lang.AssertionError: TRAP
at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_111]
at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_111]
at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:47) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:739) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:675) [server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:574) [server.jar:git-Spigot-7d78b81-f709362]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_111]
Caused by: java.lang.AssertionError: TRAP
at net.minecraft.server.v1_11_R1.ItemStack.F(ItemStack.java:94) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.ItemStack.setCount(ItemStack.java:822) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerInteractManager.a(PlayerInteractManager.java:403) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:957) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:26) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:1) ~[server.jar:git-Spigot-7d78b81-f709362]
at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:13) ~[server.jar:git-Spigot-7d78b81-f709362]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_111]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_111]
at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) ~[server.jar:git-Spigot-7d78b81-f709362]
... 5 more

Clean stacktrace formatting

Generated at Sat Dec 13 13:35:43 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.