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
- 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.
- Never hand-concatenate descriptors; derive them from MethodType.toMethodDescriptorString() or javap -s output.
- 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
- Memorize or tabulate the JVMS type codes: B C D F I J S Z V L [ — no lowercase forms.
- Generate descriptors programmatically; avoid hand-typing them.
- Check format-string templates for unsubstituted '%s' before parsing output.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Signature cannot be empty
- Extra characters at end of signature:
- Signature must start with a '(':
- Class name in signature contains '.' at index
- Truncated signature:
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/ff8ce383d6b33929.
Report an issue: GitHub.