-
-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
TheLipe edited this page Apr 17, 2026
·
2 revisions
The command class was registered without a class-level @Command.
@Command("example")
public final class ExampleCommand extends CustomCommand {
}The first parameter of a handler method is not a supported sender type.
Use one of:
CommandSenderPlayerConsoleCommandSender
The framework cannot parse a parameter type used by a handler.
Register a custom resolver:
manager.registerArgumentResolver(MyType.class, (sender, input, argument) -> {
MyType value = service.find(input);
if (value == null) {
sender.sendMessage("Not found.");
return new ArgumentResult<>(null, ResultStatus.FAIL);
}
return new ArgumentResult<>(value, ResultStatus.SUCCESS);
});Generated usage uses parameter names unless you override them with @Name.
public void teleport(CommandSender sender, @Name("player") Player target) {
}Omitted @Optional arguments are passed as null.
- use wrapper types like
Integer - null-check before use
Example:
public void give(CommandSender sender, Player target, @Optional Integer amount) {
int finalAmount = amount != null ? amount : 1;
}@Join is intended to consume the remaining raw input.
Use it on the final String argument:
public void broadcast(CommandSender sender, @Join @Name("message") String message) {
}Check the following:
- the server is Paper
- the command was registered through
CommandManager -
CommandManagerwas created withtrue, or a customCommandTabCompleteManagerwas installed - the sender has permission for the command or subcommand
- the
@TabCompletedeclaration matches the argument positions you expect
Add an unknown handler:
@Unknown(true)
public void unknown(CommandSender sender) {
sender.sendMessage("Unknown subcommand.");
}If your project has:
- project-specific permissions
- dynamic completions from configs or roles
- domain objects such as
Region,Account, orFrame
then the right pattern is:
- register custom resolvers at startup
- register custom tab completers at startup
- keep command handlers focused on command behavior, not on manual string parsing