HMCL-dev/HMCL · error · IllegalStateException

Illegal command line

Error message

Illegal command line 

What it means

DefaultLauncher.launch validates the fully assembled command line before executing the game: every token must be non-blank. If any element of rawCommandLine is blank (empty or whitespace-only string) it throws IllegalStateException("Illegal command line " + rawCommandLine), protecting against launching java with empty arguments that corrupt the command.

Solutions

  1. Review instance JVM/game argument settings and remove blank or duplicate empty entries.
  2. Check custom command prefixes (wrapper/pre-launch) for empty values and clear or fill them.
  3. Print/log rawCommandLine (it is in the exception message) to identify which token is blank.
  4. Reset the instance's advanced settings to defaults and re-add arguments carefully.

Example fix

// before (instance settings)
// jvmArgs: "-Xmx4G,, -Dfoo=bar"
// after
// jvmArgs: "-Xmx4G -Dfoo=bar"
Defensive patterns

Strategy: validation

Validate before calling

List<String> args = commandLine.toString() != null ? List.of(commandLine.toString().split("\s+")) : List.of();
boolean hasBlank = args.stream().anyMatch(String::isBlank);
if (hasBlank) { // fix instance JVM/game argument settings first }

Try / catch

try {
    launcher.launch();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Illegal command line")) {
        // inspect the printed command line; remove blank arguments from instance settings
    }
}

Prevention

When it happens

Trigger: Calling launch() when the generated command contains an empty/whitespace argument — typically caused by blank entries in JVM arguments, game arguments, classpath, or empty custom Java/wrapper settings in the instance configuration.

Common situations: Users adding an empty custom JVM argument or game argument in instance settings; empty environment-derived substitution leaving blank tokens; misconfigured memory/encoding fields producing empty strings.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/4ba6e64c6feacdab. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java:678

        return Path.of(options.getNativesDir());
    }

    @Override
    public ManagedProcess launch() throws IOException, InterruptedException {
        Path nativeFolder = getNativeFolder();

        final Command command = generateCommandLine(nativeFolder);

        // To guarantee that when failed to generate launch command line, we will not call pre-launch command
        List<String> rawCommandLine = command.commandLine.asList();

        if (command.tempNativeFolder != null) {
            Files.deleteIfExists(command.tempNativeFolder);
            Files.createSymbolicLink(command.tempNativeFolder, nativeFolder.toAbsolutePath());
        }

        if (rawCommandLine.stream().anyMatch(StringUtils::isBlank)) {
            throw new IllegalStateException("Illegal command line " + rawCommandLine);
        }

        if (!options.isUseCustomNatives()) {
            decompressNatives(command.javaNativeFolder);
        }

        if (isUsingLog4j())
            extractLog4jConfigurationFile();

        Path runDirectory = instance.getRunDirectory();

        if (StringUtils.isNotBlank(options.getPreLaunchCommand())) {
            ProcessBuilder builder = new ProcessBuilder(StringUtils.tokenize(options.getPreLaunchCommand(), getEnvVars(nativeFolder))).directory(runDirectory.toFile());
            builder.environment().putAll(getEnvVars(nativeFolder));
            SystemUtils.callExternalProcess(builder);
        }

        Process process;

View on GitHub (pinned to 24702dc5a0)