{"record":{"id":"64ca8e17c2d4ea51","repo":"HMCL-dev/HMCL","slug":"illegal-pattern-bad-escape-value","errorCode":null,"errorMessage":"Illegal pattern (Bad escape): ${value}","messagePattern":"Illegal pattern \\(Bad escape\\): (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java","lineNumber":219,"sourceCode":"            String selfVersion,\n            Path installer) {\n        this.dependencyManager = dependencyManager;\n        this.gameRepository = dependencyManager.getGameRepository();\n        this.manifest = manifest;\n        this.minecraftJar = minecraftJar;\n        this.installer = installer;\n        this.selfVersion = selfVersion;\n\n        setSignificance(TaskSignificance.MAJOR);\n    }\n\n    private static String replaceTokens(Map<String, String> tokens, String value) {\n        StringBuilder buf = new StringBuilder();\n        for (int x = 0; x < value.length(); x++) {\n            char c = value.charAt(x);\n            if (c == '\\\\') {\n                if (x == value.length() - 1)\n                    throw new IllegalArgumentException(\"Illegal pattern (Bad escape): \" + value);\n                buf.append(value.charAt(++x));\n            } else if (c == '{' || c == '\\'') {\n                StringBuilder key = new StringBuilder();\n                for (int y = x + 1; y <= value.length(); y++) {\n                    if (y == value.length())\n                        throw new IllegalArgumentException(\"Illegal pattern (Unclosed \" + c + \"): \" + value);\n                    char d = value.charAt(y);\n                    if (d == '\\\\') {\n                        if (y == value.length() - 1)\n                            throw new IllegalArgumentException(\"Illegal pattern (Bad escape): \" + value);\n                        key.append(value.charAt(++y));\n                    } else {\n                        if (c == '{' && d == '}') {\n                            x = y;\n                            break;\n                        }\n                        if (c == '\\'' && d == '\\'') {\n                            x = y;","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java#L201-L237","documentation":"Thrown as IllegalArgumentException from replaceTokens when a literal processor argument ends with a lone backslash ('\\\\' at the last character position). The escape sequence is incomplete — there is no following character to unescape — so the pattern is rejected.","triggerScenarios":"parseLiteral falls through to plainConverter.apply(replaceTokens(var, literal)); the value contains '\\\\' as its final character (x == value.length()-1). Comes from a processor arg or data value in install_profile.json with a trailing backslash (e.g. a Windows path like \"C:\\\\temp\\\\\" written with a single trailing backslash).","commonSituations":"Hand-edited or generated install_profile.json using raw Windows paths with trailing backslashes; tooling that forgot to escape backslashes (\\\\) in JSON; copy-pasted values losing an escape character.","solutions":["Fix the offending value in install_profile.json so backslashes are escaped (\\\\) or no trailing backslash remains","Regenerate the installer/profile with correct JSON escaping (write paths with \\\\ or forward slashes)","Use the official unmodified installer for that NeoForge/Forge version","If you control the code, strip or normalize trailing backslashes before parseLiteral"],"exampleFix":"// before (profile arg)\n\"--target\", \"C:\\\\minecraft\\\\\"\n// after\n\"--target\", \"C:\\\\minecraft\\\\\\\\\"","handlingStrategy":"validation","validationCode":"static boolean wellFormedLiteral(String s) {\n    return s != null && !(s.endsWith(\"\\\\\"));\n}","typeGuard":null,"tryCatchPattern":"try { task.run(); } catch (IllegalArgumentException e) { if (e.getMessage() != null && e.getMessage().startsWith(\"Illegal pattern (Bad escape)\")) reportProfileLiteralIssue(e.getMessage()); else throw e; }","preventionTips":["Escape backslashes (\\\\) in JSON profile values","Avoid trailing backslashes in Windows paths inside profiles","Validate profile literals for balanced escapes before install"],"tags":["parsing","escape-sequence","install-profile","argument"],"backgroundTag":"invalid-argument-format","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}