HMCL-dev/HMCL · error · IllegalArgumentException
Illegal pattern (Bad escape):
Error message
Illegal pattern (Bad escape):
What it means
replaceTokens scans a literal string from the Forge installer's install_profile.json data/args and interprets backslash as an escape character. If the string ends with a lone backslash there is no following character to escape, so the code throws IllegalArgumentException("Illegal pattern (Bad escape): ..."). This guards against a truncated or hand-mangled pattern in installer metadata.
Solutions
- Re-download the Forge installer from the official maven (files.minecraftforge.net) to replace the corrupted/truncated jar
- Check the value named in the message in install_profile.json inside the installer jar and fix/remove the trailing backslash
- Try a different Forge version (older or newer) whose installer format is known-good
- Update HMCL — parsing of installer data has been adjusted across versions
Example fix
// before (value in install_profile.json)
{"MAPPED_JAR": "C:\\temp\\"}
// after
{"MAPPED_JAR": "C:\\temp\\file.txt"} Defensive patterns
Strategy: validation
Validate before calling
// before installing, sanity-check installer data values
try (var zip = new java.util.zip.ZipFile(installer.toFile())) {
String json = new String(zip.getInputStream(zip.getEntry("install_profile.json")).readAllBytes());
if (json.matches(".*[^\\\\]\\\\\\"\\s*,\\s*")) throw new IllegalStateException("value ends with bare backslash");
} Try / catch
try { installTask.execute(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Illegal pattern")) { reDownloadInstaller(); } else throw e; } Prevention
- Only download installers from official Forge maven endpoints
- Never hand-edit install_profile.json inside the installer jar
- Keep HMCL updated for new installer format support
- Check file size/hash against the maven metadata before installing
When it happens
Trigger: ForgeNewInstallTask.parseLiteral is called with a literal whose last character is '\' and which is not fully wrapped in {..} or '..' — i.e. a data/processor-arg value like "path\" ending in a trailing backslash.
Common situations: Corrupted or tampered forge installer downloads; manually edited install_profile.json; forge installer formats HMCL doesn't expect (very new/old Forge releases changing data value conventions); non-Windows paths with stray trailing backslashes injected into values.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Illegal pattern (Unclosed ):
- Illegal pattern: Missing Key:
- Malformed forge installer file
- client_mappings download info not found
- Minecraft client JAR not found:
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/3942236e4c0bf5f2.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java:235
String selfVersion,
Path installer) {
this.dependencyManager = dependencyManager;
this.gameRepository = dependencyManager.getGameRepository();
this.manifest = manifest;
this.minecraftJar = minecraftJar;
this.installer = installer;
this.selfVersion = selfVersion;
setSignificance(TaskSignificance.MAJOR);
}
private static String replaceTokens(Map<String, String> tokens, String value) {
StringBuilder buf = new StringBuilder();
for (int x = 0; x < value.length(); x++) {
char c = value.charAt(x);
if (c == '\\') {
if (x == value.length() - 1)
throw new IllegalArgumentException("Illegal pattern (Bad escape): " + value);
buf.append(value.charAt(++x));
} else if (c == '{' || c == '\'') {
StringBuilder key = new StringBuilder();
for (int y = x + 1; y <= value.length(); y++) {
if (y == value.length())
throw new IllegalArgumentException("Illegal pattern (Unclosed " + c + "): " + value);
char d = value.charAt(y);
if (d == '\\') {
if (y == value.length() - 1)
throw new IllegalArgumentException("Illegal pattern (Bad escape): " + value);
key.append(value.charAt(++y));
} else {
if (c == '{' && d == '}') {
x = y;
break;
}
if (c == '\'' && d == '\'') {
x = y;View on GitHub (pinned to 24702dc5a0)