{"record":{"id":"38d918f00ad75a45","repo":"oracle/graal","slug":"invalid-trailing-characters","errorCode":null,"errorMessage":"Invalid trailing characters.","messagePattern":"Invalid trailing characters\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/APHotSpotSignature.java","lineNumber":64,"sourceCode":"    private TypeMirror returnTypeCache;\n\n    APHotSpotSignature(String signature) {\n        assert signature.length() > 0;\n        this.originalString = signature;\n\n        if (signature.charAt(0) == '(') {\n            int cur = 1;\n            while (cur < signature.length() && signature.charAt(cur) != ')') {\n                int nextCur = parseSignature(signature, cur);\n                arguments.add(signature.substring(cur, nextCur));\n                cur = nextCur;\n            }\n\n            cur++;\n            int nextCur = parseSignature(signature, cur);\n            returnType = signature.substring(cur, nextCur);\n            if (nextCur != signature.length()) {\n                throw new RuntimeException(\"Invalid trailing characters.\");\n            }\n        } else {\n            returnType = null;\n        }\n    }\n\n    private static int parseSignature(String signature, int start) {\n        int cur = start;\n        char first;\n        do {\n            first = signature.charAt(cur++);\n        } while (first == '[');\n\n        switch (first) {\n            case 'L':\n                while (signature.charAt(cur) != ';') {\n                    cur++;\n                }","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/APHotSpotSignature.java#L46-L82","documentation":"APHotSpotSignature parses a JVM method signature string such as '(II)V'. After matching the argument list in parentheses and one return-type descriptor, if characters remain the constructor throws RuntimeException('Invalid trailing characters.'). This guards against malformed signatures with garbage after the return type — typically a closing paren issue, duplicated return types, or a truncated/concatenated signature string.","triggerScenarios":"Constructing APHotSpotSignature with a string like '(I)VI', '()V extra' or '(I)' where parsing the return type ends before the end of the string: after parseSignature for the return type, nextCur != signature.length() (APHotSpotSignature.java:60-66). Happens when @MethodParameter/@Signature-style annotation values or manually built descriptor strings are malformed.","commonSituations":"Hand-written signature strings in method-substitution annotations (extra characters, missing return type then trailing text); concatenating descriptors programmatically and forgetting to stop; copy-paste from javap output including comments/flags after the descriptor.","solutions":["Fix the signature string to be exactly one method descriptor: '(<params>)<returnType>' with nothing after the return type, e.g. '(II)I'.","If building the descriptor in code, use a StringBuilder that stops after the return type and assert the final string matches the expected shape.","Validate candidate signatures against a regex or java.lang.invoke.MethodType.fromMethodDescriptorString before passing them in.","Re-run the annotation processing/build to confirm the processor accepts the signature."],"exampleFix":"// before\nnew APHotSpotSignature(\"(II)VI\"); // trailing 'I' after return type\n\n// after\nnew APHotSpotSignature(\"(II)I\");","handlingStrategy":"validation","validationCode":"static boolean isWellFormedSignature(String sig) {\n    return sig != null && sig.matches(\"\\\\((?:\\\\[*(?:[VIBCDFJSZ]|L[^;]+;))*\\\\)[VIBCDFJSZ]|L[^;]+;|\\\\[+[VIBCDFJSZ]\");\n}\n\n// or delegate to the JDK parser:\ntry {\n    MethodType.fromMethodDescriptorString(sig, ClassLoader.getSystemClassLoader());\n    return true;\n} catch (IllegalArgumentException | TypeNotPresentException e) {\n    return false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    new APHotSpotSignature(descriptor);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"trailing\")) {\n        // descriptor has text after the return type: fix the source string\n    }\n    throw e;\n}","preventionTips":["Build descriptors programmatically with MethodType.toMethodDescriptorString() instead of hand-writing them.","A method descriptor is exactly one '(...)' group followed by one return type — nothing after it.","Cross-check hand-written signatures against javap -s output for the target method."],"tags":["java","graalvm","annotation-processing","jvm-signatures","parsing","runtime-exception"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}