Skip to content

Fix NullPointerException in isHealSplash for potions with custom effects#196

Merged
dumbo-the-developer merged 2 commits intomasterfrom
copilot/fix-potiondata-error-again
Dec 1, 2025
Merged

Fix NullPointerException in isHealSplash for potions with custom effects#196
dumbo-the-developer merged 2 commits intomasterfrom
copilot/fix-potiondata-error-again

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 1, 2025

Items.isHealSplash() throws NPE when checking splash potions that have only custom_effects NBT data without a base potion type. This crashes match end handling and player death events, causing inventory loss.

Changes

  • Add null check for PotionMeta.getBasePotionData() before accessing its type
  • Store result in local variable to avoid redundant method call
// Before
return meta != null && meta.getBasePotionData().getType() == PotionType.INSTANT_HEAL;

// After
final PotionData potionData = meta.getBasePotionData();
return potionData != null && potionData.getType() == PotionType.INSTANT_HEAL;

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • hub.spigotmc.org
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • jitpack.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • libraries.minecraft.net
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • maven.enginehub.org
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • mvn-repo.arim.space
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • nexus.sirblobman.xyz
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • repo.artillex-studios.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • repo.codemc.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • repo.essentialsx.net
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • repo.extendedclip.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)
  • repo.papermc.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Lost items -> PotionData error</issue_title>
<issue_description>### Server version

1.21.5

Duels version

4.2

Plugin list

Duels

Describe the bug

Hello, players were playing duel & then one player died and disconnected:

[16:10:35] [Server thread/INFO]: ☠ gaming_Krish ❤10 died by SreekarSela hand who used Netherite Sword
[16:10:35] [Server thread/INFO]: [DeluxeCombat] Player is not fighting at the moment!
[16:10:35] [Server thread/INFO]: [DeluxeCombat] SreekarSela is no longer tagged.
[16:10:35] [luckperms-command-executor/INFO]: [LP] sreekarsela does not temporarily inherit from combat in context global.
[16:10:35] [luckperms-command-executor/INFO]: [LP] gaming_krish does not have grapplinghook.pull.self set in context server=lifesteal_clans.
[16:10:35] [luckperms-command-executor/INFO]: [LP] gaming_krish does not have combatnot set temporarily in context server=lifesteal_clans.
[16:10:35] [Server thread/WARN]: [Duels] Task dumbo-the-developer/Duels#19765399 for Duels v4.2 generated an exception
java.lang.NullPointerException: Cannot invoke "org.bukkit.potion.PotionData.getType()" because the return value of "org.bukkit.inventory.meta.PotionMeta.getBasePotionData()" is null
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.util.compat.Items.isHealSplash(Items.java:101) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.gui.inventory.InventoryGui.<init>(InventoryGui.java:26) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.inventories.InventoryManager.create(InventoryManager.java:69) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.duel.DuelManager.lambda$handleMatchEnd$4(DuelManager.java:111) ~[Duels-Optimised-4.2.jar:?]
	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.duel.DuelManager.lambda$handleMatchEnd$7(DuelManager.java:111) ~[Duels-Optimised-4.2.jar:?]
	at org.bukkit.craftbukkit.scheduler.CraftTask.run(CraftTask.java:78) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:474) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1707) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1566) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1284) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:299) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]

then after a while the winner wasn't teleported to spawn so he disconnected too, btu then he lost inventory.

[16:10:44] [Server thread/WARN]: gaming_Krish was kicked due to keepalive timeout!
[16:10:44] [Server thread/INFO]: gaming_Krish lost connection: Timed out
[16:12:27] [Server thread/INFO]: SreekarSela lost connection: Disconnected
[16:12:27] [Server thread/INFO]: ☠ SreekarSela ❤10 died by gaming_Krish hand who used Sad Ending
[16:12:27] [Server thread/ERROR]: Could not pass event PlayerDeathEvent to Duels v4.2
java.lang.NullPointerException: Cannot invoke "org.bukkit.potion.PotionData.getType()" because the return value of "org.bukkit.inventory.meta.PotionMeta.getBasePotionData()" is null
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.util.compat.Items.isHealSplash(Items.java:101) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.gui.inventory.InventoryGui.<init>(InventoryGui.java:26) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.inventories.InventoryManager.create(InventoryManager.java:69) ~[Duels-Optimised-4.2.jar:?]
	at Duels-Optimised-4.2.jar/com.meteordevelopments.duels.duel.DuelManager$DuelListener.on(DuelManager.java:477) ~[Duels-Optimised-4.2.jar:?]
	at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:71) ~[leaf-api-1.21.5-R0.1-SNAPSHOT.jar:?]
	at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:71) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:629) ~[leaf-api-1.21.5-R0.1-SNAPSHOT.jar:?]
	at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerDeathEvent(CraftEventFactory.java:922) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at net.minecraft.server.level.ServerPlayer.die(ServerPlayer.java:1072) ~[leaf-1.21.5.jar:1.21.5-68-ceae9d1]
	at org.bukkit.craftbukkit.entity.CraftLivingEntity.setHealth(CraftLivingEntity.java:135) ~[leaf-1.21.5.jar:1...

</details>

- Fixes dumbo-the-developer/Duels#144

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for you](https://github.com/dumbo-the-developer/Duels/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

… custom effects

Co-authored-by: dumbo-the-developer <83227054+dumbo-the-developer@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix PotionData error in duels plugin Fix NullPointerException in isHealSplash for potions with custom effects Dec 1, 2025
@dumbo-the-developer
Copy link
Copy Markdown
Owner

@copilot will this support custom potions?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Dec 1, 2025

@copilot will this support custom potions?

Yes, the fix supports custom potions in that they no longer cause a crash. Custom potions (those with only custom_effects NBT data and no base potion type) will return false from isHealSplash() since getBasePotionData() returns null for them. This is the expected behavior - the method specifically checks for standard instant heal splash potions based on the base potion type, not custom effects. If you need custom healing potions to be detected, that would require additional logic to iterate through custom effects.

@dumbo-the-developer dumbo-the-developer marked this pull request as ready for review December 1, 2025 00:29
@dumbo-the-developer dumbo-the-developer merged commit 600cb4b into master Dec 1, 2025
5 checks passed
@dumbo-the-developer dumbo-the-developer deleted the copilot/fix-potiondata-error-again branch December 1, 2025 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants