oracle/graal · error · ParserException.ClassFormatError
invalid descriptor: {}
Error message
invalid descriptor: {} What it means
TypeSymbols.parse handles single-character (primitive) descriptors via JavaKind.fromPrimitiveOrVoidTypeChar. When that single character is not a valid primitive/void letter ('Z C F D B S I J V'), the failure is wrapped as ParserException.ClassFormatError 'invalid descriptor: <desc>' — i.e. the descriptor is one character long but meaningless, such as 'X', 'A', or lowercase 'i'.
Source
Thrown at espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java:201
return kind.getType();
}
/**
* Parses a valid Java type descriptor.
*
* @param descriptor the raw signature from which to create a Java type descriptor
* @param beginIndex the index within the string from which to start parsing
* @param slashes specifies if package components in {@code string} are separated by {@code '/'}
* or {@code '.'}
* @throws ParserException.ClassFormatError if the type descriptor is not valid
*/
Symbol<Type> parse(Symbol<? extends Descriptor> descriptor, int beginIndex, boolean slashes) throws ParserException.ClassFormatError {
int endIndex = skipValidTypeDescriptor(descriptor, beginIndex, slashes);
if (endIndex == beginIndex + 1) {
try {
return forPrimitive(JavaKind.fromPrimitiveOrVoidTypeChar((char) descriptor.byteAt(beginIndex)));
} catch (IllegalStateException e) {
throw new ParserException.ClassFormatError("invalid descriptor: " + descriptor);
}
}
return symbols.getOrCreate(descriptor.subSequence(beginIndex, endIndex));
}
/**
* Verifies that a valid type descriptor is at {@code beginIndex} in {@code type}.
*
* @param slashes specifies if package components are separated by {@code '/'} or {@code '.'}
* @return the index one past the valid type descriptor starting at {@code beginIndex}
* @throws ParserException.ClassFormatError if there is no valid type descriptor
*/
@TruffleBoundary
static int skipValidTypeDescriptor(Symbol<? extends Descriptor> descriptor, int beginIndex, boolean slashes) throws ParserException.ClassFormatError {
if (beginIndex >= descriptor.length()) {
throw new ParserException.ClassFormatError("invalid type descriptor: " + descriptor);
}
char ch = (char) descriptor.byteAt(beginIndex);View on GitHub (pinned to a66e9ccd1d)
Solutions
- Use the canonical JVM descriptor letters: Z=boolean C=char F=float D=double B=byte S=short I=int J=long V=void, references 'L...;' arrays '[...'
- Add a descriptor validator in your generator before emitting class files so errors surface at generation time with file context
- Check for case errors — all primitive letters are uppercase
Example fix
// before
Symbol<Type> t = typeSymbols.parse(symbolOf("i"), 0, true); // lowercase
// after
Symbol<Type> t = typeSymbols.parse(symbolOf("I"), 0, true); // JVM int descriptor Defensive patterns
Strategy: validation
Validate before calling
if (desc.length() == 1 && "ZCFDBSIJV".indexOf(desc.charAt(0)) < 0) throw new IllegalArgumentException("Bad primitive descriptor: " + desc); Type guard
static boolean isValidPrimitiveDescriptor(String d) { return d.length() == 1 && "ZCFDBSIJV".indexOf(d.charAt(0)) >= 0; } Try / catch
catch (ParserException.ClassFormatError e) { include the descriptor and generating class in the error } Prevention
- Use only uppercase JVM primitive letters in generators
- Validate descriptors at class-file generation time where you still have source context
When it happens
Trigger: A one-character type descriptor that is not a JVM primitive letter — typos like 'i' instead of 'I', 'x', 'P'; or a truncated multi-char descriptor that happened to be cut to its first bad character.
Common situations: Hand-written or templated descriptor strings in bytecode generators; case errors (JVM letters are uppercase); descriptors copied from human-readable documentation ('int') instead of JVM form ('I').
Related errors
- unknown primitive or void type character:
- 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/cda7074108bb39cd.
Report an issue: GitHub.