oracle/graal · error · IllegalArgumentException
unknown primitive or void type character:
Error message
unknown primitive or void type character:
What it means
JavaKind.fromPrimitiveOrVoidTypeChar maps a single JVM type descriptor character to a JavaKind: Z,C,F,D,B,S,I,J,V. Any other character (including 'L' for references or '[' for arrays, which this method intentionally does not handle) yields IllegalArgumentException 'unknown primitive or void type character'.
Source
Thrown at espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/JavaKind.java:261
public static JavaKind fromWordSize(int wordSizeInBytes) {
if (wordSizeInBytes == 8) {
return JavaKind.Long;
} else {
assert wordSizeInBytes == 4 : "Unsupported word size!";
return JavaKind.Int;
}
}
/**
* Returns the kind from the character describing a primitive or void. An exception is thrown if
* the character doesn't correspond to any primitive or void type.
*
* @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()}
*/
public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
JavaKind kind = fromPrimitiveOrVoidTypeCharOrNull(ch);
if (kind == null) {
throw new IllegalArgumentException(invalidTypeCharMessage(ch));
}
return kind;
}
/**
* Returns the kind from the character describing a primitive or void. If the character doesn't
* correspond to any primitive or void type, null is returned.
*
* @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()}
*/
public static JavaKind fromPrimitiveOrVoidTypeCharOrNull(char ch) {
return switch (ch) {
case 'Z' -> Boolean;
case 'C' -> Char;
case 'F' -> Float;
case 'D' -> Double;
case 'B' -> Byte;
case 'S' -> Short;View on GitHub (pinned to a66e9ccd1d)
Solutions
- Filter reference/array descriptors first: if the first char is 'L' or '[', it is JavaKind.Object and must not go through this method
- Use the null-safe sibling fromPrimitiveOrVoidTypeCharOrNull(ch) and branch on null instead of relying on the exception
- Validate generated descriptors against the JVM spec letters (Z C F D B S I J V) before parsing
Example fix
// before JavaKind k = JavaKind.fromPrimitiveOrVoidTypeChar(desc.charAt(0)); // fails on 'L' or '[' // after JavaKind k = JavaKind.fromPrimitiveOrVoidTypeCharOrNull(desc.charAt(0)); if (k == null) k = (desc.charAt(0) == 'L' || desc.charAt(0) == '[') ? JavaKind.Object : null;
Defensive patterns
Strategy: validation
Validate before calling
JavaKind k = JavaKind.fromPrimitiveOrVoidTypeCharOrNull(ch);
if (k == null && ch != 'L' && ch != '[') throw new IllegalArgumentException("Bad descriptor char: " + ch); Type guard
static boolean isPrimitiveOrVoidChar(char c) { return "ZCFDBSIJV".indexOf(c) >= 0; } Try / catch
catch (IllegalArgumentException e) { report the offending descriptor string and index, not just the char } Prevention
- Check for 'L'/'[' (reference/array) before calling the primitive mapper
- Prefer the OrNull variant in parsers and branch on null
When it happens
Trigger: Calling fromPrimitiveOrVoidTypeChar with the first char of a descriptor without first checking for 'L'/'[' (e.g. feeding 'Ljava/lang/String;' -> 'L'); descriptor strings with a typo like 'l' or 'i' lowercase; empty/garbage descriptor input from bytecode the tool generated.
Common situations: Writing a bytecode parser or generator that assumes every descriptor is primitive; passing class-file descriptors obtained from reflection (getType() char) without filtering reference types; case confusion between JVM spec letters and their lowercase forms.
Related errors
- invalid descriptor: {}
- invalid type descriptor: {}
- Invalid Java name {}
- Array with more than 255 dimensions {}
- Invalid type descriptor {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/10ae011739ab5e72.
Report an issue: GitHub.