HMCL-dev/HMCL · error · IllegalArgumentException
The extension of is not 'bat' or 'ps1' in Windows
Error message
The extension of is not 'bat' or 'ps1' in Windows
What it means
DefaultLauncher.makeLaunchScript writes a launch script and requires, on Windows, a .bat extension (unless PowerShell .ps1 was selected). It throws IllegalArgumentException("The extension of <file> is not 'bat' or 'ps1' in Windows") when the script file path on a Windows host has any other extension, because the generated script format would not be runnable.
Solutions
- Use a .bat file name when exporting the launch script on Windows (or .ps1 for PowerShell).
- Rename the target script file's extension to .bat before calling makeLaunchScript.
- On a Windows machine that needs a shell script, export .ps1 instead of .sh.
- Pick the export format according to the current OS rather than a fixed path.
Example fix
// before
// launcher.makeLaunchScript(Path.of("game.sh"), ...); // on Windows
// after
// launcher.makeLaunchScript(Path.of("game.bat"), ...); // on Windows Defensive patterns
Strategy: validation
Validate before calling
String ext = FileUtils.getExtension(scriptFile);
boolean isWindows = OS.WINDOWS == OperatingSystem.CURRENT_OS;
if (isWindows && !"ps1".equals(ext) && !"bat".equalsIgnoreCase(ext)) {
throw new IllegalArgumentException("Use .bat or .ps1 on Windows, got: " + ext);
} Try / catch
try {
launcher.makeLaunchScript(scriptFile, ...);
} catch (IllegalArgumentException e) {
// rename the script file to .bat or .ps1 and retry
} Prevention
- Choose the script extension based on the current OS
- Never hardcode .sh paths in Windows export flows
- Strip accidental .txt suffixes added by editors
When it happens
Trigger: Calling makeLaunchScript(scriptFile, ...) on Windows with a file whose extension is not bat/ps1 — e.g. saving a launch script as .sh or .txt while running on Windows.
Common situations: Users exporting a script to share with Linux friends while on Windows; saving with a .txt extension added by a text editor; automation passing a fixed filename without checking OS.
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
- The extension of is not 'sh', 'bash', 'ps1' or 'command'…
- Minecraft jar does not exist
- Main class is null for instance
- Illegal command line
- Unable to move temp file from
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/d0a4ba09b428c6ce.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java:871
// With ModLauncher, OptiFine is discovered via HMCLTransformerDiscoveryService, not classpath.
!GameComponentAnalyzer.MOD_LAUNCHER_MAIN.equals(manifest.mainClass())) {
classpath.add(FileUtils.getAbsolutePath(selectedOptiFineInstallerFile));
}
return classpath;
}
@Override
public void makeLaunchScript(Path scriptFile) throws IOException {
boolean isWindows = OperatingSystem.WINDOWS == OperatingSystem.CURRENT_OS;
Path nativeFolder = getNativeFolder();
String scriptExtension = FileUtils.getExtension(scriptFile);
boolean usePowerShell = "ps1".equals(scriptExtension);
if (!usePowerShell) {
if (isWindows && !scriptExtension.equalsIgnoreCase("bat"))
throw new IllegalArgumentException("The extension of " + scriptFile + " is not 'bat' or 'ps1' in Windows");
else if (!isWindows && !(scriptExtension.equalsIgnoreCase("sh") || scriptExtension.equalsIgnoreCase("command") || scriptExtension.equalsIgnoreCase("bash")))
throw new IllegalArgumentException("The extension of " + scriptFile + " is not 'sh', 'bash', 'ps1' or 'command' in macOS/Linux");
}
final Command commandLine = generateCommandLine(nativeFolder);
final String command = usePowerShell ? null : commandLine.commandLine.toString();
Map<String, String> envVars = getEnvVars(nativeFolder);
if (isWindows && !usePowerShell) {
// https://stackoverflow.com/a/28452546
// https://learn.microsoft.com/troubleshoot/windows-client/shell-experience/command-line-string-limitation
if (command.length() > 32767) {
throw new CommandTooLongException();
}
}
if (isUsingLog4j())
extractLog4jConfigurationFile();View on GitHub (pinned to 24702dc5a0)