{"record":{"id":"b1efe6e6bfb53133","repo":"quarkusio/quarkus","slug":"invalid-signature-char","errorCode":null,"errorMessage":"Invalid signature char: ","messagePattern":"Invalid signature char: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java","lineNumber":426,"sourceCode":"                    int end = argsSignature.indexOf(';', i);\n                    String binaryName = argsSignature.substring(i + 1, end);\n                    // arrays take the entire signature\n                    if (dimensions > 0) {\n                        args.add(Type.create(DotName.createSimple(argsSignature.substring(start, end + 1).replace('/', '.')),\n                                Kind.ARRAY));\n                        dimensions = 0;\n                    } else {\n                        // class names take only the binary name\n                        args.add(Type.create(DotName.createSimple(binaryName.replace('/', '.')), Kind.CLASS));\n                    }\n                    i = end; // we will have a ++ to get after the ;\n                    start = i + 1;\n                    break;\n                case '[':\n                    dimensions++;\n                    break;\n                default:\n                    throw new IllegalStateException(\"Invalid signature char: \" + c);\n            }\n        }\n        return args.toArray(new Type[0]);\n    }\n\n    /**\n     * Returns the number of underlying bytecode parameters taken by the given Jandex parameter Type.\n     * This will be 2 for doubles and longs, 1 otherwise.\n     *\n     * @param paramType the Jandex parameter Type\n     * @return the number of underlying bytecode parameters required.\n     */\n    public static int getParameterSize(Type paramType) {\n        if (paramType.kind() == Kind.PRIMITIVE) {\n            switch (paramType.asPrimitiveType().primitive()) {\n                case DOUBLE:\n                case LONG:\n                    return 2;","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java#L408-L444","documentation":"AsmUtil.getParameterTypes parses a JVM method descriptor string (e.g. (IJ)Ljava/lang/String;) into Jandex Types. Any character in the argument section that is not a primitive descriptor char (Z B C D F I J S), 'L', or '[' throws IllegalStateException(\"Invalid signature char: \"), meaning the descriptor is malformed or uses a construct the simple parser does not support (e.g. 'V' for void arguments, 'T' type-variable signatures).","triggerScenarios":"Passing a string that is not a well-formed method descriptor to AsmUtil.getParameterTypes — e.g. including the return type, a generic signature like (TT;)V or (Ljava/util/List<Ljava/lang/String;>;)V, or a truncated/corrupted descriptor.","commonSituations":"Hand-building descriptors in tests or recorders; passing a generic signature (from ClassInfo.genericSignature) instead of the plain descriptor; reading descriptors from non-class files.","solutions":["Pass only the plain bytecode descriptor (method.descriptor()), not the generic signature — Jandex exposes the descriptor via MethodInfodescriptor()/name 'descriptor'","Strip everything outside the parentheses and ensure only legal descriptor chars are inside","Validate the descriptor with a regex like ^\\((\\[*[ZBCDFIJS]|\\[*L[^;:<>]+;)*\\).+$ before calling","If you have a Jandex MethodInfo, prefer method.parameterTypes() over parsing the descriptor manually"],"exampleFix":"// before\nType[] params = AsmUtil.getParameterTypes(method.genericSignature());\n// after\nType[] params = method.parameterTypes(); // or use method.descriptor()","handlingStrategy":"validation","validationCode":"private static final java.util.regex.Pattern DESCRIPTOR =\n    java.util.regex.Pattern.compile(\"^\\\\((\\\\[*[ZBCDFIJS]|\\\\[*L[^.;<>\\\\[\\\\]]*;)*\\\\)\\\\[*(V|Z|B|C|D|F|I|J|S|L[^.;<>\\\\[\\\\]]*;)$\");\nif (!DESCRIPTOR.matcher(methodDescriptor).matches()) {\n    throw new IllegalArgumentException(\"Not a plain method descriptor: \" + methodDescriptor);\n}\n","typeGuard":"static boolean isPlainMethodDescriptor(String s) {\n    return s.startsWith(\"(\") && s.contains(\")\") && !s.contains(\"<\") && !s.contains(\"T;\");\n}\n","tryCatchPattern":"try {\n    Type[] params = AsmUtil.getParameterTypes(desc);\n} catch (IllegalStateException e) {\n    throw new IllegalArgumentException(\"Malformed method descriptor '\" + desc + \"'\", e);\n}\n","preventionTips":["Use MethodInfo.descriptor()/parameterTypes() instead of parsing signatures by hand","Never pass generic signatures (with <>) where a plain descriptor is expected","Validate descriptors with a regex before parsing"],"tags":["bytecode","jandex","descriptor-parsing"],"backgroundTag":"invalid-method-descriptor","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}