
🐞 Issue: NPE when right-clicking tropical fish with invalid Variant (Skript 2.12.2 + Paper 1.21.4)
uwuhhhj opened this issue · 4 comments
Skript/Server Version
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Skript's aliases can be found here: https://github.com/SkriptLang/skript-aliases
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Skript's documentation can be found here: https://docs.skriptlang.org/
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Skript's tutorials can be found here: https://docs.skriptlang.org/tutorials
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Server Version: 1.21.4-2416-51aafbc (MC: 1.21.4)
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Skript Version: 2.12.2 (skriptlang-github)
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Installed Skript Addons: None
[16:44:55] [Render thread/INFO]: [System] [CHAT] [Skript] Installed dependencies: None
Bug Description
When right-clicking a tropical fish entity that was summoned with an invalid NBT Variant value (e.g. Variant:-9), Skript 2.12.2 throws a NullPointerException in the right click event handler.
This happens even with a minimal script that only broadcasts a message (no direct use of fish properties). The stack trace shows the error originates from ch.njol.skript.entity.TropicalFishData.init, where TropicalFish#getPattern() is null and .ordinal() is called without a null check.
Expected Behavior
Right-clicking any entity, including tropical fish with unusual or malformed NBT data, should not crash Skript or throw a NullPointerException.
If the entity’s data (such as tropical fish Pattern) is invalid or null, Skript should handle it gracefully by either:
Falling back to a safe default value, or
Skipping that field entirely.
In either case, the event should continue to run normally instead of failing with a severe error.
Steps to Reproduce
Steps to reproduce
Set up the environment
Server: Paper 1.21.4 (R0.1-SNAPSHOT)
Plugin: Skript 2.12.2 (no addons required)
Java: 24.0.1
Create a minimal script at plugins/Skript/scripts/right_click.sk:
on right click:
set {_who} to player
set {_e} to event-entity
broadcast "&7[probe] enter onRightClick: player=%name of {_who}%, entity=%type of {_e}%"
Reload the script
/skript reload right_click.sk
Baseline check (works)
Join the server.
Spawn any normal mob, e.g.:
/summon minecraft:zombie ~ ~ ~
Right-click the zombie.
Observed: The broadcast appears; no errors.
Reproduction
Summon a tropical fish with an invalid Variant:
/summon minecraft:tropical_fish ~ ~ ~ {Variant:-9}
Right-click the summoned fish.
Observe console output
Skript prints a Severe Error with a stack trace ending in:
Caused by: java.lang.NullPointerException:
Cannot invoke "org.bukkit.entity.TropicalFish$Pattern.ordinal()"
because the return value of "org.bukkit.entity.TropicalFish.getPattern()" is null
at ch.njol.skript.entity.TropicalFishData.init(TropicalFishData.java:67)
...
Current trigger: right click (right_click.sk, line 1)
Thread: Server thread
Errors or Screenshots
[15:36:47 INFO]: Loliiiico joined the game
[15:36:47 INFO]: Loliiiico[/59.132.66.170:46256] logged in with entity id 19 at ([world]96.80529680261188, 65.11650136792812, -72.10660419692827)
[15:40:32 INFO]: Loliiiico issued server command: /skript reload right_click.sk
[15:40:48 INFO]: [probe] enter onRightClick: player=Loliiiico, entity=zombie
[15:40:50 INFO]: [probe] enter onRightClick: player=Loliiiico, entity=zombie
[15:42:28 INFO]: Loliiiico issued server command: /summon tropical_fish ~ ~ ~ {Variant:-9}
[15:42:28 INFO]: [Loliiiico: Summoned new Tropical Fish]
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! [Skript] Severe Error:
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! An unexpected error occurred with Skript. This issue is likely not your fault.
[15:42:35 ERROR]: #!#! Report the issue: https://github.com/SkriptLang/Skript/issues
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! Stack trace:
[15:42:35 ERROR]: #!#! Caused by: java.lang.NullPointerException: Cannot invoke "org.bukkit.entity.TropicalFish$Pattern.ordinal()" because the return value of "org.bukkit.entity.TropicalFish.getPattern()" is null
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.entity.TropicalFishData.init(TropicalFishData.java:67)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.entity.TropicalFishData.init(TropicalFishData.java:15)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.entity.EntityData.getData(EntityData.java:705)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.entity.EntityData.fromEntity(EntityData.java:738)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//org.skriptlang.skript.lang.converter.Converters.convert(Converters.java:405)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.Variable.getConverted(Variable.java:482)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.Variable.getAll(Variable.java:781)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.Variable.getArray(Variable.java:773)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.expressions.base.PropertyExpression.get(PropertyExpression.java:193)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.util.SimpleExpression.getArray(SimpleExpression.java:86)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.VariableString.getMessageComponents(VariableString.java:426)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.effects.EffBroadcast.execute(EffBroadcast.java:86)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.Effect.run(Effect.java:42)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.TriggerItem.walk(TriggerItem.java:40)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.TriggerItem.walk(TriggerItem.java:67)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.lang.Trigger.execute(Trigger.java:33)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.SkriptEventHandler.lambda$execute$2(SkriptEventHandler.java:165)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.SkriptEventHandler.lambda$execute$3(SkriptEventHandler.java:176)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.util.Task.callSync(Task.java:147)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.util.Task.callSync(Task.java:131)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.SkriptEventHandler.execute(SkriptEventHandler.java:174)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.SkriptEventHandler.check(SkriptEventHandler.java:120)
[15:42:35 ERROR]: #!#! at Skript-2.12.2.jar//ch.njol.skript.SkriptEventHandler$PriorityListener.lambda$new$0(SkriptEventHandler.java:46)
[15:42:35 ERROR]: #!#! at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80)
[15:42:35 ERROR]: #!#! at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70)
[15:42:35 ERROR]: #!#! at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54)
[15:42:35 ERROR]: #!#! at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131)
[15:42:35 ERROR]: #!#! at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628)
[15:42:35 ERROR]: #!#! at net.minecraft.server.network.ServerGamePacketListenerImpl$3.performInteraction(ServerGamePacketListenerImpl.java:2848)
[15:42:35 ERROR]: #!#! at net.minecraft.server.network.ServerGamePacketListenerImpl$3.onInteraction(ServerGamePacketListenerImpl.java:2899)
[15:42:35 ERROR]: #!#! at net.minecraft.network.protocol.game.ServerboundInteractPacket$InteractionAction.dispatch(ServerboundInteractPacket.java:140)
[15:42:35 ERROR]: #!#! at net.minecraft.network.protocol.game.ServerboundInteractPacket.dispatch(ServerboundInteractPacket.java:91)
[15:42:35 ERROR]: #!#! at net.minecraft.server.network.ServerGamePacketListenerImpl.handleInteract(ServerGamePacketListenerImpl.java:2838)
[15:42:35 ERROR]: #!#! at net.minecraft.network.protocol.game.ServerboundInteractPacket.handle(ServerboundInteractPacket.java:78)
[15:42:35 ERROR]: #!#! at net.minecraft.network.protocol.game.ServerboundInteractPacket.handle(ServerboundInteractPacket.java:14)
[15:42:35 ERROR]: #!#! at net.minecraft.network.protocol.PacketUtils.lambda$ensureRunningOnSameThread$0(PacketUtils.java:29)
[15:42:35 ERROR]: #!#! at net.minecraft.server.TickTask.run(TickTask.java:18)
[15:42:35 ERROR]: #!#! at net.minecraft.util.thread.BlockableEventLoop.doRunTask(BlockableEventLoop.java:155)
[15:42:35 ERROR]: #!#! at net.minecraft.util.thread.ReentrantBlockableEventLoop.doRunTask(ReentrantBlockableEventLoop.java:24)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:1494)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:176)
[15:42:35 ERROR]: #!#! at net.minecraft.util.thread.BlockableEventLoop.pollTask(BlockableEventLoop.java:129)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:1474)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:1468)
[15:42:35 ERROR]: #!#! at net.minecraft.util.thread.BlockableEventLoop.managedBlock(BlockableEventLoop.java:139)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.managedBlock(MinecraftServer.java:1425)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:1433)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1310)
[15:42:35 ERROR]: #!#! at net.minecraft.server.MinecraftServer.lambda$spin$2(MinecraftServer.java:313)
[15:42:35 ERROR]: #!#! at java.base/java.lang.Thread.run(Thread.java:1447)
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! Skript: 2.12.2 (unknown)
[15:42:35 ERROR]: #!#! Flavor: skriptlang-github
[15:42:35 ERROR]: #!#! Date: 16:08:22.181400100
[15:42:35 ERROR]: #!#! Bukkit: 1.21.4-R0.1-SNAPSHOT
[15:42:35 ERROR]: #!#! Minecraft: 1.21.4
[15:42:35 ERROR]: #!#! Java: 24.0.1 (OpenJDK 64-Bit Server VM 24.0.1+9)
[15:42:35 ERROR]: #!#! OS: Linux amd64 6.8.0-63-generic
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! Server platform: Paper
[15:42:35 ERROR]: #!#!
[15:42:35 ERROR]: #!#! Current node: null
[15:42:35 ERROR]: #!#! Current item: broadcast "§7[probe] enter onRightClick: player=%name of {_who} (as java.lang.Object)%, entity=%type of {_e} (as java.lang.Object)%"
[15:42:35 ERROR]: #!#! Current trigger: right click (rightclick) (right_click.sk, line 1)
[15:42:35 ERROR]: #!#! Thread: Server thread
[15:42:35 ERROR]: #!#! Language: english
[15:42:35 ERROR]: #!#! Link parse mode: DISABLED
[15:42:35 ERROR]: #!#! End of Error.
[15:42:35 ERROR]: #!#!
Other
Additional context
The error does not depend on script complexity. It occurs even with a minimal right-click handler that only broadcasts a string.
This suggests the problem occurs during Skript’s internal conversion of the clicked entity to EntityData, not in user script logic.
The root cause appears to be TropicalFishData.init assuming TropicalFish#getPattern() is always non-null. In cases where Bukkit returns null (due to an invalid NBT Variant), this causes an immediate NullPointerException.
A simple null check before calling .ordinal() should prevent the crash.
Workaround for users: Avoid summoning tropical fish with invalid or negative Variant values.
But for fish like this that already exist in the world, is it necessary to avoid registering a right-click with the Skript script? Until the plugin author fixes this.
Agreement
- I have read the guidelines above and affirm I am following them with this report.
pls use purpur 1.21.4 to test ,https://purpurmc.org/download/purpur/1.21.4 100% is bug

Personally, I feel this should be a bug with Paper and it's downstreams such as Purpur. Since getting the Tropical Fish Pattern of a Tropical Fish is annotated as NotNull
and should always have a Tropical Fish Pattern when being spawned.
However, #7985 does fix this issue, but not exactly intended for that, as it focuses on if a new Tropical Fish Pattern was ever added.
Yes, this is a problem with paper/purpur. They are not properly handling this case and returning null when they promise to never do so. We could add a check ourselves, but since it's for such a niche case and we're technically doing everything properly already, I am not much inclined to do so. Is there any reason a user would want a fish with an invalid pattern?