HMCL-dev/HMCL · error · IllegalArgumentException

Illegal pattern (Unclosed ):

Error message

Illegal pattern (Unclosed ): 

What it means

replaceTokens treats '{' and '\'' as openers of token references ({KEY}) or quoted literals ('...'). If the scan reaches the end of the string without finding the matching closer, it throws IllegalArgumentException("Illegal pattern (Unclosed <c>): <value>"). The message text appears with a trailing space because the closer char is appended as 'Unclosed ' + c where c is '{' or '\''.

Solutions

  1. Re-download the Forge installer from official sources to rule out corruption
  2. Open the installer jar, inspect install_profile.json data values named in the message, and add the missing closing brace/quote
  3. Use a different Forge version known to install correctly
  4. Update HMCL to the latest version for broader installer-format compatibility

Example fix

// before (data value)
{"SRC": "{MINECRAFT_LIBS}"
// after
{"SRC": "{MINECRAFT_LIBS}"}
Defensive patterns

Strategy: validation

Validate before calling

// verify balanced braces/quotes in installer profile values before running
long open = json.chars().filter(c -> c == '{').count();
long close = json.chars().filter(c -> c == '}').count();
if (open != close) throw new IllegalStateException("unbalanced braces in install_profile.json");

Try / catch

try { installTask.execute(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Unclosed")) { reDownloadInstaller(); } else throw e; }

Prevention

When it happens

Trigger: A data value or processor argument passed to parseLiteral (not fully wrapped in {..} or '..') contains a '{' or '\'' with no matching '}' or '\'' before end of string, e.g. value "unclosed{KEY".

Common situations: Corrupted forge installer downloads; hand-edited install_profile.json dropping a closing brace/quote; unexpected installer format from very new Forge versions; values where a lone quote is used as an apostrophe in prose.

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


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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java:241

        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;
                            break;
                        }
                        key.append(d);
                    }
                }
                if (c == '\'') {

View on GitHub (pinned to 24702dc5a0)