quarkusio/quarkus · error · IllegalStateException

Unable to find top command. Ensure you have a @CommandDefini

Error message

Unable to find top command. Ensure you have a @CommandDefinition class or set the quarkus.aesh.top-command property.

What it means

The Quarkus AESH extension builds a CLI runner but found no top-level command to execute. The factory first honors quarkus.aesh.top-command, then the build-time detected @CommandDefinition class; when neither yields a command it fails fast with this IllegalStateException at application startup.

Source

Thrown at extensions/aesh/runtime/src/main/java/io/quarkus/aesh/runtime/DefaultAeshRuntimeRunnerFactory.java:62

            AeshRuntimeRunner runner = AeshRuntimeRunner.builder()
                    .containerBuilder(new AeshCdiCommandContainerBuilder<>())
                    .command(commandInstance);
            if (settings.commandInvocationProvider() != null) {
                runner.commandInvocationProvider(
                        (org.aesh.command.invocation.CommandInvocationProvider<?>) settings.commandInvocationProvider());
            }
            if (settings.converterInvocationProvider() != null) {
                runner.converterInvocationProvider(settings.converterInvocationProvider());
            }
            if (settings.validatorInvocationProvider() != null) {
                runner.validatorInvocationProvider(settings.validatorInvocationProvider());
            }
            if (defaultValueProvider.isResolvable()) {
                runner.defaultValueProvider(defaultValueProvider.get());
            }
            return runner;
        }
        throw new IllegalStateException(
                "Unable to find top command. Ensure you have a @CommandDefinition class "
                        + "or set the quarkus.aesh.top-command property.");
    }

    @SuppressWarnings("unchecked")
    private Command<?> resolveTopCommand() {
        // 1. Explicit config property overrides everything
        if (configuration.topCommand().isPresent()) {
            String topCommandName = configuration.topCommand().get();
            return loadCommand(topCommandName);
        }

        // 2. Use the build-time detected top command
        String topClassName = aeshContext.getTopCommandClassName();
        if (topClassName != null) {
            return loadCommand(topClassName);
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate a class implementing org.aesh.command.Command with @CommandDefinition(name=..., description=...) so it is detected as the top command.
  2. Or set quarkus.aesh.top-command=<fully.qualified.ClassName> in application.properties pointing at an existing Command implementation.

Example fix

// before
public class HelloCommand { /* no annotation, not a Command */ }
// after
@CommandDefinition(name = "hello", description = "Says hello")
public class HelloCommand implements Command<CommandResult> {
    public CommandResult execute(CommandInvocation ci) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

if (ConfigProvider.getConfig().getOptionalValue("quarkus.aesh.top-command", String.class).isEmpty()) {
    // ensure exactly one class is annotated @CommandDefinition and implements org.aesh.command.Command
}

Prevention

When it happens

Trigger: DefaultAeshRuntimeRunnerFactory.create() runs at startup when resolveTopCommand() returns null: quarkus.aesh.top-command is unset AND no class annotated with @CommandDefinition was discovered at build time.

Common situations: Adding the quarkus-aesh extension but never defining a CLI command; misspelling or omitting @CommandDefinition; expecting the extension to work without any command class.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7317fce4487e21b7. Report an issue: GitHub.