{"record":{"id":"bf341d0d7e5b9f6f","repo":"java-decompiler/jd-gui","slug":"signaturewriter-writesignature-invalid-signature","errorCode":null,"errorMessage":"SignatureWriter.WriteSignature: invalid signature '${descriptor}'","messagePattern":"SignatureWriter\\.WriteSignature: invalid signature '(.+?)'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java","lineNumber":168,"sourceCode":"                    beginIndex = ++index;\n                    index = descriptor.substring(beginIndex, length).indexOf(';');\n                    sb.append(descriptor.substring(beginIndex, index));\n                    index++;\n                    break;\n                case 'V': sb.append(\"void\"); index++; break;\n                case 'Z': sb.append(\"boolean\"); index++; break;\n                case '-':\n                    sb.append(\"? super \");\n                    index = writeSignature(sb, descriptor, length, index+1, false);\n                    break;\n                case '+':\n                    sb.append(\"? extends \");\n                    index = writeSignature(sb, descriptor, length, index+1, false);\n                    break;\n                case '*': sb.append('?'); index++; break;\n                case 'X': case 'Y': sb.append(\"int\"); index++; break;\n                default:\n                    throw new RuntimeException(\"SignatureWriter.WriteSignature: invalid signature '\" + descriptor + \"'\");\n            }\n\n            if (varargsFlag) {\n                if (dimensionLength > 0) {\n                    while (--dimensionLength > 0)\n                        sb.append(\"[]\");\n                    sb.append(\"...\");\n                }\n            } else {\n                while (dimensionLength-- > 0)\n                    sb.append(\"[]\");\n            }\n\n            if ((index >= length) || (descriptor.charAt(index) != '.'))\n                break;\n\n            sb.append('.');\n        }","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/java-decompiler/jd-gui/blob/b3c1ced04e571fc316648d114ff0c8121e051d8f/services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java#L150-L186","documentation":"The signature writer in AbstractTypeFactoryProvider converts JVM type descriptors (e.g. 'Ljava/lang/String;') into readable Java types. When it encounters a character at the start of a type that is not a recognized descriptor or wildcard/signature marker (invalid 'BaseType' character), it throws a RuntimeException naming the whole descriptor. This guards against corrupted class files or descriptors that were truncated or parsed at a wrong index.","triggerScenarios":"writeSignature (or writeMethodSignature via it) processing a descriptor whose current character is not one of B/C/D/F/I/J/S/V/Z/L/T/[/*+/-/X/Y — typically a truncated descriptor, an index pointing mid-identifier, or a class file with corrupted constant-pool/Signature attributes.","commonSituations":"Opening a class file compiled by a non-standard or buggy compiler; obfuscated or deliberately malformed bytecode; a JD-GUI version not supporting newer signature constructs (e.g. some compilations with X/Y handling); passing a method descriptor instead of a field/type descriptor into the type factory.","solutions":["Verify the class file is valid: recompile or re-obtain the artifact from a trusted source (javap -v can confirm the Signature/descriptor attributes).","Check that the descriptor string passed to the type factory is a full type descriptor and not truncated or offset — a wrong starting index lands mid-identifier and hits the default branch.","Upgrade JD-GUI to the latest release; support for signature encodings has been extended over time.","If you maintain the code, log the failing index and character before throwing to pinpoint which construct is unsupported."],"exampleFix":"// before\ndefault:\n    throw new RuntimeException(\"SignatureWriter.WriteSignature: invalid signature '\" + descriptor + \"'\");\n// after\ndefault:\n    if (Character.isJavaIdentifierStart(c)) { // fallback: treat as class name char\n        sb.append(c); index++; break;\n    }\n    throw new RuntimeException(\"SignatureWriter.WriteSignature: invalid signature '\" + descriptor + \"' at index \" + index + \" char '\" + c + \"'\");","handlingStrategy":"validation","validationCode":"// Check the descriptor starts with a legal BaseType/ObjectType/ArrayType char\nboolean isLikelyValidTypeDescriptor(String d) {\n    if (d == null || d.isEmpty()) return false;\n    char c = d.charAt(0);\n    return \"BCDFIJSVZ\".indexOf(c) >= 0 || c == 'L' || c == '[' || c == 'T' || c == '+' || c == '-' || c == '*';\n}","typeGuard":"boolean isObjectTypeDescriptor(String d) {\n    return d != null && d.startsWith(\"L\") && d.endsWith(\";\");\n}","tryCatchPattern":"try {\n    String readable = typeFactory.make(api, entry, descriptor).getDisplayTypeName();\n} catch (RuntimeException ex) {\n    if (ex.getMessage() != null && ex.getMessage().startsWith(\"SignatureWriter.WriteSignature:\")) {\n        // fall back to showing the raw descriptor\n        readable = descriptor;\n    } else throw ex;\n}","preventionTips":["Only pass complete type descriptors (never truncated or index-offset strings) into signature rendering","Validate class files before decompiling (javap -v or a class-file verifier)","Keep JD-GUI updated for newer signature encodings","Log descriptor plus current index/char before throwing to aid diagnosis"],"tags":["java","bytecode","signature","jvm-descriptor"],"backgroundTag":"invalid-argument-format","analyzedSha":"b3c1ced04e571fc316648d114ff0c8121e051d8f","analyzedAt":"2026-09-06T02:34:31.263Z","contentChangedAt":"2026-09-06T02:34:31.263Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}