HMCL-dev/HMCL · error · IllegalArgumentException

bad query string

Error message

bad query string

What it means

HMCLMultiMCBootstrap.parseQuery splits the query string on '&' and expects each token to contain at most one '='. When a token splits into zero or more than two parts (empty token or multiple '=' signs), it throws IllegalArgumentException("bad query string"). This guards the bootstrap from malformed launch arguments.

Solutions

  1. Remove empty segments (consecutive or trailing '&') from the query string before it reaches HMCL.
  2. URL-encode any '=' characters inside values (%3D) so each segment has at most one '='.
  3. If you control the caller, sanitize/split the query string yourself and pass only well-formed name=value pairs.

Example fix

// before
parseQuery("server=example.com&token=abc==")
// after
parseQuery("server=example.com&token=abc%3D%3D")
Defensive patterns

Strategy: validation

Validate before calling

boolean isSafeQuery(String q) {
    if (q == null || q.isEmpty()) return true; // or false per contract
    for (String part : q.split("&", -1)) {
        if (part.isEmpty()) return false;
        if (part.indexOf('=') != part.lastIndexOf('=')) return false;
    }
    return true;
}
// call: if (!isSafeQuery(query)) throw new IllegalArgumentException("malformed query: " + query);

Try / catch

try {
    Map<String,String> params = parseQuery(query);
} catch (IllegalArgumentException e) {
    LOG.warn("Skipping malformed query string: " + query, e);
    params = Collections.emptyMap();
}

Prevention

When it happens

Trigger: Calling parseQuery with a string containing an empty '&amp;' segment (e.g. 'a=1&&b=2' or a trailing '&'), or a segment with two or more '=' characters such as 'base64data=abc==', since split("=") then yields 3+ parts.

Common situations: Malformed command-line or launcher-supplied query parameters; base64 values embedded in query strings without URL encoding; hand-edited shortcut/target lines with stray '&' or '='; trailing delimiters left by template expansion.

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/095ffc7cd9b77913. Report an issue: GitHub.

Appendix: source

Thrown at minecraft/libraries/HMCLMultiMCBootstrap/src/main/java/org/jackhuang/hmcl/HMCLMultiMCBootstrap.java:98

                method.invoke(null, (Object) args);
                return;
            }
        }

        throw new IllegalArgumentException("Cannot find method 'main(String[])' in " + mainClass);
    }

    private static Map<String, String> parseQuery(String queryParameterString) {
        if (queryParameterString == null) return Collections.emptyMap();

        Map<String, String> result = new HashMap<>();

        try (Scanner scanner = new Scanner(queryParameterString)) {
            scanner.useDelimiter("&");
            while (scanner.hasNext()) {
                String[] nameValue = scanner.next().split("=");
                if (nameValue.length == 0 || nameValue.length > 2) {
                    throw new IllegalArgumentException("bad query string");
                }

                String name = decodeURL(nameValue[0]);
                String value = nameValue.length == 2 ? decodeURL(nameValue[1]) : null;
                result.put(name, value);
            }
        }
        return result;
    }

    private static String decodeURL(String value) {
        try {
            return URLDecoder.decode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new AssertionError(e);
        }
    }
}

View on GitHub (pinned to 24702dc5a0)