oracle/graal · error · IllegalArgumentException
Malformed method variant name: %s
Error message
Malformed method variant name: %s
What it means
Method.splitMethodVariantName throws IllegalArgumentException when a name contains the '%%' separator but the substring between the separator and the last '(' is empty or the name has no '(' at all — i.e. the 'method%%key(signature)' shape cannot be reconstructed. keyEnd = lastIndexOf('('); if it is missing or precedes keyBegin, the name is malformed.
Source
Thrown at compiler/src/org.graalvm.profdiff/src/org/graalvm/profdiff/core/Method.java:259
*
* For example, if the argument is {@code java.util.HashMap.size%%key()}, this method returns
* {@code java.util.HashMap.size()} and {@code key}.
*
* If the provided method name does not contain a method variant key, {@code null} is returned
* in place of the method variant key.
*
* @param methodVariantName a method variant name
* @return the method name and method variant key
*/
public static Pair<String, String> splitMethodVariantName(String methodVariantName) {
int separatorBegin = methodVariantName.indexOf(StableMethodNameFormatter.METHOD_VARIANT_KEY_SEPARATOR);
if (separatorBegin == -1) {
return Pair.create(methodVariantName, null);
}
int keyBegin = separatorBegin + StableMethodNameFormatter.METHOD_VARIANT_KEY_SEPARATOR.length();
int keyEnd = methodVariantName.lastIndexOf('(');
if (keyEnd == -1 || keyBegin > keyEnd) {
throw new IllegalArgumentException("Malformed method variant name: " + methodVariantName);
}
String methodName = methodVariantName.substring(0, separatorBegin) + methodVariantName.substring(keyEnd);
String methodVariantKey = methodVariantName.substring(keyBegin, keyEnd);
return Pair.create(methodName, methodVariantKey);
}
/**
* Returns a method name (removing the method variant key) from the given method variant name.
*
* @param methodVariantName name of a method variant (optionally containing a method variant
* key)
* @return method name corresponding to the given method variant
*/
public static String removeMethodVariantKey(String methodVariantName) {
return splitMethodVariantName(methodVariantName).getLeft();
}
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Ensure names keep the canonical 'holder%%key(signature)' form before splitting.
- Pre-check with a validation regex or contains('(') before calling splitMethodVariantName.
- For names without '%%' the method already returns (name, null) — only pass variant-carrying names that also have a signature.
Example fix
// before
Pair<String,String> p = Method.splitMethodVariantName("java.util.Foo%%noSig");
// after
Pair<String,String> p = Method.splitMethodVariantName("java.util.Foo%%v0(int)"); Defensive patterns
Strategy: validation
Validate before calling
static boolean isWellFormedVariantName(String n) {
int sep = n.indexOf("%%");
if (sep == -1) return true;
int paren = n.lastIndexOf('(');
return paren != -1 && sep + 2 <= paren;
} Type guard
static boolean isWellFormedVariantName(String n) {
int sep = n.indexOf("%%");
if (sep == -1) return true;
int paren = n.lastIndexOf('(');
return paren != -1 && sep + 2 <= paren;
} Try / catch
try {
Method.splitMethodVariantName(name);
} catch (IllegalArgumentException e) {
// message contains the malformed name; log it and skip the entry
} Prevention
- Do not strip parentheses when post-processing method names.
- Keep the 'holder%%key(signature)' shape intact.
When it happens
Trigger: Calling splitMethodVariantName("foo%%") (separator but no '('), splitMethodVariantName("foo%%(") (empty key, keyBegin > keyEnd when key sits after the last paren position is impossible), or hand-mangled names where the only '(' appears before the '%%'.
Common situations: Post-processing or user edits of optimization-log method names that drop the signature; regex-based munging that strips parentheses; logs from tools that emit names not following the stable formatter's shape.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- The provided argument is a method variant name: %s
- classForNode method shall return node class representation r
- Cannot compare {JavaLangRuntimeVersion.__name__} to {type(ot
- Out of scratch registers: %s
- Should be recognized as signature:
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/ac3d3dce6f20a2bd.
Report an issue: GitHub.