oracle/graal · error · IllegalArgumentException

Invalid character '

Error message

Invalid character '

What it means

IllegalArgumentException from SignatureUtil.parseParameterSignature: after consuming any '[' array prefixes, the next character of a parameter/return type is not one of the valid JVMS type codes ('B','C','D','F','I','J','S','Z','V','L'). The message names the offending character, its index, and the full signature, so malformed type codes like 'u', 'A', or a stray '(' inside the parameter list are pinpointed.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/util/SignatureUtil.java:141

        }
    }

    /**
     * Checks if the given signature can be successfully parsed by
     * {@link #parseSignature(String, List)}.
     *
     * @param signature the signature to check
     * @param acceptMissingReturnType whether a signature without a return type is considered to be
     *            valid
     * @return whether the signature can be successfully parsed
     */
    public static boolean isSignatureValid(String signature, boolean acceptMissingReturnType) {
        return parseSignatureInternal(signature, null, false, acceptMissingReturnType) != null;
    }

    private static <T> T throwOrReturn(boolean shouldThrow, T returnValue, String errorMessage) {
        if (shouldThrow) {
            throw new IllegalArgumentException(errorMessage);
        } else {
            return returnValue;
        }
    }
}

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Look at the character and index in the message and correct that type code against the JVMS table: B byte, C char, D double, F float, I int, J long, S short, Z boolean, V void, L...; object, [ array.
  2. Never hand-concatenate descriptors; derive them from MethodType.toMethodDescriptorString() or javap -s output.
  3. Validate external input with SignatureUtil.isSignatureValid(sig, false) and reject early.

Example fix

// before
String sig = "(i)V"; // lowercase 'i' invalid

// after
String sig = "(I)V";
Defensive patterns

Strategy: validation

Validate before calling

private static final String VALID_TYPE_CHARS = "BCDFIJSZVL[";
static boolean hasPlausibleTypeCodes(String sig) {
    for (int i = 0; i < sig.length(); i++) {
        char c = sig.charAt(i);
        if ("()[".indexOf(c) < 0 && VALID_TYPE_CHARS.indexOf(c) < 0) return false;
    }
    return SignatureUtil.isSignatureValid(sig, false);
}

Try / catch

try {
    SignatureUtil.parseSignature(sig, params);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Invalid character")) {
        reportDescriptorTypo(sig, e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: Calling SignatureUtil.parseSignature with descriptors containing an invalid type letter — e.g. '(u)V' (lowercase), '(LA;)V' (missing 'java/' style but valid shape is fine; invalid only when first char after '[' is not a code), '()[xV', or where a parameter descriptor was mangled by templating ('%s' left unsubstituted).

Common situations: Hand-building descriptor strings with typos; format-string placeholders never filled in; lowercase/uppercase confusion ('i' vs 'I'); descriptors from a non-JVM source (e.g. .NET-style 'System.Int32') fed into JVM tooling.

Understand the failure class

Related errors


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