HMCL-dev/HMCL · error · IllegalArgumentException
The extension of is not 'sh', 'bash', 'ps1' or 'command'…
Error message
The extension of is not 'sh', 'bash', 'ps1' or 'command' in macOS/Linux
What it means
DefaultLauncher.makeLaunchScript requires that on macOS/Linux the script file extension be sh, bash, command, or ps1 (ps1 selects PowerShell output). It throws IllegalArgumentException("The extension of <file> is not 'sh', 'bash', 'ps1' or 'command' in macOS/Linux") when the target file has another extension on a non-Windows host.
Solutions
- Use a .sh (or .bash/.command/.ps1) file name when exporting on macOS/Linux.
- Rename the script file extension to .sh before calling makeLaunchScript.
- Branch on the OS in your code to choose the correct extension, as the launcher itself does with isWindows.
- Remember to chmod +x the generated .sh script afterwards to make it executable.
Example fix
// before
// launcher.makeLaunchScript(Path.of("game.bat"), ...); // on Linux
// after
// launcher.makeLaunchScript(Path.of("game.sh"), ...); // on Linux Defensive patterns
Strategy: validation
Validate before calling
String ext = FileUtils.getExtension(scriptFile);
boolean isWindows = OS.WINDOWS == OperatingSystem.CURRENT_OS;
if (!isWindows && !"ps1".equals(ext) && !("sh".equalsIgnoreCase(ext) || "bash".equalsIgnoreCase(ext) || "command".equalsIgnoreCase(ext))) {
throw new IllegalArgumentException("Use .sh/.bash/.command/.ps1 on macOS/Linux, got: " + ext);
} Try / catch
try {
launcher.makeLaunchScript(scriptFile, ...);
} catch (IllegalArgumentException e) {
// rename the script file to .sh (or .ps1) and retry
} Prevention
- Never export .bat scripts on macOS/Linux; map to .sh instead
- OS-branch extension selection in automation/CI scripts
- chmod +x generated shell scripts after export
When it happens
Trigger: Calling makeLaunchScript(scriptFile, ...) on Linux/macOS with a file whose extension is not one of sh/bash/command/ps1 — e.g. exporting game.bat or game.txt on a Linux machine.
Common situations: Copy-pasting a Windows-oriented export path (.bat) on Linux; text editors appending .txt; CI scripts generating scripts with a fixed .bat name regardless of 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 'bat' or 'ps1' in Windows
- Cannot locate 'osascript' system executable on MacOS for…
- Minecraft jar does not exist
- Main class is null for instance
- Illegal command line
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/87f7338079b22718.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java:873
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();
if (!options.isUseCustomNatives())View on GitHub (pinned to 24702dc5a0)