Paper tries to register Brigadier commands from disabled plugins (causes NPE)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 3.5k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 11
Description
Stack trace
Time: 2025-10-10 15:17:56
Description: Exception in server tick loop
java.lang.NullPointerException: Exception in server tick loop
at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at io.papermc.paper.command.brigadier.APICommandMeta.plugin(APICommandMeta.java:25)
at io.papermc.paper.command.brigadier.PaperBrigadier.wrapNode(PaperBrigadier.java:55)
at io.papermc.paper.command.brigadier.bukkit.BukkitBrigForwardingMap$Values$1.next(BukkitBrigForwardingMap.java:198)
at io.papermc.paper.command.brigadier.bukkit.BukkitBrigForwardingMap$Values$1.next(BukkitBrigForwardingMap.java:172)
at java.base/java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1078)
at org.bukkit.craftbukkit.help.SimpleHelpMap.initializeCommands(SimpleHelpMap.java:127)
at org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:619)
at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:743)
at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:488)
at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:280)
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1164)
at net.minecraft.server.MinecraftServer.lambda$spin$2(MinecraftServer.java:310)
at java.base/java.lang.Thread.run(Thread.java:1583)
Plugin and Datapack List
only my personal plugin.
Actions to reproduce (if known)
see below. you can reproduce with any plugin that uses brigadier and have requirement.
Paper version
[15:17:39] [ServerMain/INFO]: [bootstrap] Loading Paper 1.21.8-60-main@29c8822 (2025-09-06T21:49:13Z) for Minecraft 1.21.8
i can't paste like example because it crashes in bootstrap.
seems every versions on using brigadier.
(occurs on paper-1.21.10-64 too. )
Other
i made a simple Paper plugin that requires Skript.
name: TestPlugin1
version: '1.0-SNAPSHOT'
main: kim.biryeong.testplugin.TestPlugin
api-version: '1.21'
authors: [ biryeongtrain ]
description: test
bootstrapper: kim.biryeong.testplugin.TestPluginBootstrapper
dependencies:
server:
Skript:
load: BEFORE
required: true
join-classpath: true
in paper-plugin.yml
package kim.biryeong.testplugin;
import org.bukkit.plugin.java.JavaPlugin;
public final class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
// Plugin startup logic
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
}
in TestPlugin.java
public class TestPluginBootstrapper implements PluginBootstrap {
private final Logger LOGGER = LoggerFactory.getLogger(TestPluginBootstrapper.class);
@Override
public void bootstrap(BootstrapContext bootstrapContext) {
LOGGER.info("TestPluginBootstrapper bootstrap called");
bootstrapContext.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands -> {
LiteralCommandNode<CommandSourceStack> test = Commands.literal("paper-command-test")
.build();
LiteralCommandNode<CommandSourceStack> test_child = Commands.literal("test")
.executes(ctx -> {
ctx.getSource().getExecutor().sendMessage("Hello World!");
return 1;
})
.build();
commands.registrar().register(test);
test.addChild(test_child);
});
}
}
in TestPluginBootstrapper.java
and then I just ran Paper without the required dependency.
PaperTest
├── plugins
│ └── testPlugin.jar (paper-plugin that requires Skript. uses brigadier for register its command)
└── paper-1.21.10-64.jar
first, Paper executes the plugin’s bootstrap since it doesn’t have any dependencies during the bootstrap phase.
[15:46:58] [ServerMain/INFO]: [PluginInitializerManager] Paper plugins (1):
- TestPlugin1 (1.0-SNAPSHOT)
[15:46:58] [ServerMain/INFO]: [kim.biryeong.testplugin.TestPluginBootstrapper] TestPluginBootstrapper bootstrap called
after the server section, Paper disables my test plugin because Skript is missing. (yes, this is not a bug.)
[15:22:30] [Server thread/ERROR]: [ModernPluginLoadingStrategy] Could not load 'plugins\TestPlugin1-1.0-SNAPSHOT.jar' in 'plugins'
org.bukkit.plugin.UnknownDependencyException: Unknown/missing dependency plugins: [Skript]. Please download and install these plugins to run 'TestPlugin1'.
at io.papermc.paper.plugin.entrypoint.strategy.modern.ModernPluginLoadingStrategy.loadProviders(ModernPluginLoadingStrategy.java:82) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at io.papermc.paper.plugin.storage.SimpleProviderStorage.enter(SimpleProviderStorage.java:38) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler.enter(LaunchEntryPointHandler.java:39) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:555) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:323) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1230) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at net.minecraft.server.MinecraftServer.lambda$spin$2(MinecraftServer.java:353) ~[paper-1.21.10.jar:1.21.10-64-fba780d]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
when all plugins are loaded, Paper tries to initialize commands. however, my test plugin’s command also remains queued for registration.
java.lang.NullPointerException: null
at java.base/java.util.Objects.requireNonNull(Objects.java:233) ~[?:?]
at io.papermc.paper.command.brigadier.APICommandMeta.plugin(APICommandMeta.java:25) ~[paper-1.21.8.jar:?]
at io.papermc.paper.command.brigadier.PaperBrigadier.wrapNode(PaperBrigadier.java:55) ~[paper-1.21.8.jar:?]
at io.papermc.paper.command.brigadier.bukkit.BukkitBrigForwardingMap$Values$1.next(BukkitBrigForwardingMap.java:198) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at io.papermc.paper.command.brigadier.bukkit.BukkitBrigForwardingMap$Values$1.next(BukkitBrigForwardingMap.java:172) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at java.base/java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1078) ~[?:?]
at org.bukkit.craftbukkit.help.SimpleHelpMap.initializeCommands(SimpleHelpMap.java:127) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:619) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:743) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:488) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:280) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1164) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at net.minecraft.server.MinecraftServer.lambda$spin$2(MinecraftServer.java:310) ~[paper-1.21.8.jar:1.21.8-60-29c8822]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
@NullMarked
public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List<String> aliases, @Nullable String helpCommandNamespace) {
public APICommandMeta(final @Nullable PluginMeta pluginMeta, final @Nullable String description) {
this(pluginMeta, description, Collections.emptyList(), null);
}
public APICommandMeta {
aliases = List.copyOf(aliases);
}
@Nullable
public Plugin plugin() {
return this.pluginMeta == null ? null : Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.pluginMeta.getName()));
}
public APICommandMeta withAliases(List<String> registeredAliases) {
return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace);
}
}
the problem is here: the commands I registered still have a PluginMeta, because they were registered through Paper Brigadier.
however, since my plugin is disabled, it can’t retrieve the Plugin instance.
you can see full log at here : https://mclo.gs/jpynYpe
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with APICommandMeta.plugin(), PaperBrigadier.wrapNode(), and BukkitBrigForwardingMap.Values, then reproduce the missing-Skript dependency case described in the issue. Trace how the queued Brigadier command reaches SimpleHelpMap.initializeCommands; done means a plugin disabled for a missing dependency no longer causes server startup to throw a NullPointerException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100