oracle/graal · warning · InvalidArgumentException

no subcommand named '%s'

Error message

no subcommand named '%s'

What it means

InvalidArgumentException (via CommandParsingException path) from CommandGroup.parse: args[offset] does not match any subcommand name registered with addCommand. CommandGroup models a node in a command hierarchy (e.g. 'mx foo <subcommand> ...'); when the token selects no registered subcommand, parsing stops with 'no subcommand named <arg>' naming the offending token.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/args/CommandGroup.java:66

     *
     * @param name the name of the command group
     * @param defaultCommand the command selected by default
     * @param help the help message
     */
    public CommandGroup(String name, C defaultCommand, String help) {
        super(name, defaultCommand, help);
    }

    /**
     * Parses and updates the selected subcommand based on {@code args[offset]}.
     *
     * @see Command#parse(String[], int)
     */
    public int parse(String[] args, int offset) throws InvalidArgumentException, HelpRequestedException, CommandParsingException {
        String arg = args[offset];
        value = subCommands.get(arg);
        if (value == null) {
            throw new InvalidArgumentException(getName(), String.format("no subcommand named '%s'", arg));
        }
        return value.parse(args, offset + 1);
    }

    @Override
    public final boolean parseValue(String arg) throws InvalidArgumentException {
        throw GraalError.unimplementedOverride();
    }

    /**
     * Adds a command to the set of subcommands.
     */
    public C addCommand(C command) {
        subCommands.put(command.getName(), command);
        return command;
    }

    /**

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Run the tool with its help flag to list registered subcommands and correct the spelling/order.
  2. Ensure global options come after (or in the position the parser expects) the subcommand token so the subcommand slot holds a real subcommand.
  3. If extending the tool, register your subcommand via addCommand with the exact name (case-sensitive map lookup).
  4. On upgrade, check the changelog for renamed subcommands.

Example fix

# before
$ mx graal comppile ...   # typo

# after
$ mx graal compile ...      # registered subcommand
Defensive patterns

Strategy: validation

Validate before calling

// If you embed CommandGroup, pre-check tokens before parse
Set<String> known = subCommandNames; // maintained next to addCommand calls
if (offset < args.length && !known.contains(args[offset])) {
    printUsage(known);
    throw new InvalidArgumentException(getName(), "unknown subcommand '" + args[offset] + "'");
}

Try / catch

try {
    group.parse(args, 0);
} catch (CommandParsingException | InvalidArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("no subcommand named")) {
        printHelpAndListSubcommands(group);
    } else throw e;
}

Prevention

When it happens

Trigger: Invoking a CLI built on CommandGroup with a misspelled or unregistered subcommand: value = subCommands.get(arg) returns null and the error is thrown before recursion into value.parse continues.

Common situations: Typos ('verison' for 'version'); subcommands available only in a different build/distribution; a subcommand renamed or removed in a newer version of the tool; extra global flags placed before the subcommand token so a flag name lands at args[offset].

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/72f4d048156fc68e. Report an issue: GitHub.