PaperMC / PaperMC/Paper

Paper tries to register Brigadier commands from disabled plugins (causes NPE)

Open
#13,163 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: needs triage
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

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.