{"record":{"id":"cda7074108bb39cd","repo":"oracle/graal","slug":"invalid-descriptor","errorCode":null,"errorMessage":"invalid descriptor: {}","messagePattern":"invalid descriptor: (.+?)","errorType":"exception","errorClass":"ParserException.ClassFormatError","httpStatus":null,"severity":"error","filePath":"espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java","lineNumber":201,"sourceCode":"        return kind.getType();\n    }\n\n    /**\n     * Parses a valid Java type descriptor.\n     *\n     * @param descriptor the raw signature from which to create a Java type descriptor\n     * @param beginIndex the index within the string from which to start parsing\n     * @param slashes specifies if package components in {@code string} are separated by {@code '/'}\n     *            or {@code '.'}\n     * @throws ParserException.ClassFormatError if the type descriptor is not valid\n     */\n    Symbol<Type> parse(Symbol<? extends Descriptor> descriptor, int beginIndex, boolean slashes) throws ParserException.ClassFormatError {\n        int endIndex = skipValidTypeDescriptor(descriptor, beginIndex, slashes);\n        if (endIndex == beginIndex + 1) {\n            try {\n                return forPrimitive(JavaKind.fromPrimitiveOrVoidTypeChar((char) descriptor.byteAt(beginIndex)));\n            } catch (IllegalStateException e) {\n                throw new ParserException.ClassFormatError(\"invalid descriptor: \" + descriptor);\n            }\n        }\n        return symbols.getOrCreate(descriptor.subSequence(beginIndex, endIndex));\n    }\n\n    /**\n     * Verifies that a valid type descriptor is at {@code beginIndex} in {@code type}.\n     *\n     * @param slashes specifies if package components are separated by {@code '/'} or {@code '.'}\n     * @return the index one past the valid type descriptor starting at {@code beginIndex}\n     * @throws ParserException.ClassFormatError if there is no valid type descriptor\n     */\n    @TruffleBoundary\n    static int skipValidTypeDescriptor(Symbol<? extends Descriptor> descriptor, int beginIndex, boolean slashes) throws ParserException.ClassFormatError {\n        if (beginIndex >= descriptor.length()) {\n            throw new ParserException.ClassFormatError(\"invalid type descriptor: \" + descriptor);\n        }\n        char ch = (char) descriptor.byteAt(beginIndex);","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java#L183-L219","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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').","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"],"exampleFix":"// before\nSymbol<Type> t = typeSymbols.parse(symbolOf(\"i\"), 0, true); // lowercase\n\n// after\nSymbol<Type> t = typeSymbols.parse(symbolOf(\"I\"), 0, true); // JVM int descriptor","handlingStrategy":"validation","validationCode":"if (desc.length() == 1 && \"ZCFDBSIJV\".indexOf(desc.charAt(0)) < 0) throw new IllegalArgumentException(\"Bad primitive descriptor: \" + desc);","typeGuard":"static boolean isValidPrimitiveDescriptor(String d) { return d.length() == 1 && \"ZCFDBSIJV\".indexOf(d.charAt(0)) >= 0; }","tryCatchPattern":"catch (ParserException.ClassFormatError e) { include the descriptor and generating class in the error }","preventionTips":["Use only uppercase JVM primitive letters in generators","Validate descriptors at class-file generation time where you still have source context"],"tags":["espresso","classfile","descriptor","parsing"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}