oracle/graal · error · IllegalArgumentException
unknown primitive or void type character:
Error message
unknown primitive or void type character:
What it means
Thrown by APHotSpotSignature while resolving a single type-signature character to a javax.lang.model TypeKind during annotation processing. The signature grammar only accepts the JVM primitive/void characters 'Z','C','F','D','B','S','I','J','V' at this position; any other character means the signature string being parsed is not a valid JVM method/type descriptor. This class is used by the Graal annotation processor to parse @MethodSubstitution/@NodeIntrinsic style signatures, so the exception indicates a malformed signature literal in processor input.
Source
Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/APHotSpotSignature.java:181
return TypeKind.BOOLEAN;
case 'C':
return TypeKind.CHAR;
case 'F':
return TypeKind.FLOAT;
case 'D':
return TypeKind.DOUBLE;
case 'B':
return TypeKind.BYTE;
case 'S':
return TypeKind.SHORT;
case 'I':
return TypeKind.INT;
case 'J':
return TypeKind.LONG;
case 'V':
return TypeKind.VOID;
}
throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
}
public TypeMirror getReturnType(ProcessingEnvironment env) {
if (returnTypeCache == null) {
if (returnType == null) {
throw new RuntimeException("Invalid return type.");
}
returnTypeCache = lookupType(env, returnType);
}
return returnTypeCache;
}
@Override
public String toString() {
return "Signature<" + originalString + ">";
}
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Correct the signature string to be a valid JVM descriptor: parentheses-wrapped parameter descriptors followed by exactly one return descriptor (e.g. "(ILjava/lang/String;)J").
- Use fully qualified slash-separated names for reference types ('Ljava/lang/Object;') and '[' prefixes for arrays; do not use '.', '<', or source-type names.
- If the signature is derived, print the string being parsed at the construction site and compare it against javap output for the target method.
- Add a unit test that constructs APHotSpotSignature for every substitution signature to catch typos at build time.
Example fix
// before @MethodSubstitution(value = "append", signature = "(ljava/lang/String;)i") // after @MethodSubstitution(value = "append", signature = "(Ljava/lang/String;)I")
Defensive patterns
Strategy: validation
Validate before calling
private static final String PRIM = "ZCFDBSIJV";
static boolean isValidPrimitiveChar(char ch) { return PRIM.indexOf(ch) >= 0; }
// validate whole descriptor before parsing:
static boolean isValidDescriptor(String sig) {
return sig.matches("\\((\\[*(Z|C|F|D|B|S|I|J|L[^;]+;))*\\)(\\[*(Z|C|F|D|B|S|I|J|V|L[^;]+;))");
} Try / catch
try { sig.lookupType(env); } catch (IllegalArgumentException e) { messager.printMessage(Diagnostic.Kind.ERROR, "bad signature '" + sig + "': " + e.getMessage(), element); } Prevention
- Generate descriptors from Element objects (executableElement.getParameters + return type) instead of hand-writing strings.
- Add a descriptor-format unit test for every signature constant.
- Remember reference types must be 'L<name>;' with slashes, not dots.
When it happens
Trigger: A method signature string like "(Ljava/lang/Object;)X" or "hello" is handed to the APHotSpotSignature constructor; lookupType later calls the primitive-switch and falls through on 'X', 'L' at the wrong position, '[' , lowercase letters, or any non-descriptor character. Only the eight primitive chars plus 'V' reach this switch, so any Object/array return in a spot expecting a primitive char, or a typo in a signature annotation attribute, triggers it.
Common situations: Hand-writing a signature in a replacements annotation (e.g. @MethodSubstitution(isStatic = ..., signature = ...)), typo'ing the return descriptor ("I" vs "i", "V" vs "void"), or pasting a partial descriptor that omits the leading '(' or the return character. Also occurs after refactoring a substituted method's signature without updating the annotation string.
Related errors
- Invalid return type.
- Invalid replay boolean flag
- Required replay field is null
- Unexpected architecture name ${archName}
- A negative probability of + probabilityValue + is not allo
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/3f6c5416994e9c41.
Report an issue: GitHub.