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

  1. Ensure names keep the canonical 'holder%%key(signature)' form before splitting.
  2. Pre-check with a validation regex or contains('(') before calling splitMethodVariantName.
  3. 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

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

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/ac3d3dce6f20a2bd. Report an issue: GitHub.