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
- Remove empty segments (consecutive or trailing '&') from the query string before it reaches HMCL.
- URL-encode any '=' characters inside values (%3D) so each segment has at most one '='.
- 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
- URL-encode '=' (%3D) inside values so each segment has one '='.
- Join parameters with a helper that avoids empty or duplicate '&' segments.
- Trim trailing delimiters before parsing.
- Unit-test parseQuery with edge inputs ('', 'a&&b', 'a=b=c').
When it happens
Trigger: Calling parseQuery with a string containing an empty '&' 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
- Cannot find method 'main(String[])' in
- Invalid data URI
- name existing
- Texture url is empty
- Failed to download texture
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)