{"record":{"id":"63ca2246d3b52086","repo":"java-decompiler/jd-gui","slug":"signature-format-exception-descriptor","errorCode":null,"errorMessage":"Signature format exception: '${descriptor}'","messagePattern":"Signature format exception: '(.+?)'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java","lineNumber":213,"sourceCode":"            sb.append(\"{...}\");\n        } else {\n            boolean isAConstructor = methodName.equals(\"<init>\");\n\n            if (isAConstructor) {\n                sb.append(constructorName);\n            } else {\n                sb.append(methodName);\n            }\n\n            // Skip generics\n            int length = descriptor.length();\n            int index = 0;\n\n            while ((index < length) && (descriptor.charAt(index) != '('))\n                index++;\n\n            if (descriptor.charAt(index) != '(') {\n                throw new RuntimeException(\"Signature format exception: '\" + descriptor + \"'\");\n            }\n\n            sb.append('(');\n\n            // pass '('\n            index++;\n\n            if (descriptor.charAt(index) != ')') {\n                if (isAConstructor && isInnerClass && ((typeAccess & Type.FLAG_STATIC) == 0)) {\n                    // Skip first parameter\n                    int lengthBackup = sb.length();\n                    index = writeSignature(sb, descriptor, length, index, false);\n                    sb.setLength(lengthBackup);\n                }\n\n                if (descriptor.charAt(index) != ')') {\n                    int varargsParameterIndex;\n","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/java-decompiler/jd-gui/blob/b3c1ced04e571fc316648d114ff0c8121e051d8f/services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java#L195-L231","documentation":"writeMethodSignature renders a JVM method descriptor (which must start with '(' for the parameter list). If no '(' is found anywhere in the descriptor, the code throws a RuntimeException with the offending descriptor. This means the string passed is not a valid JVM method descriptor at all — a structural sanity check before parsing parameters.","triggerScenarios":"writeMethodSignature called with a descriptor string that contains no '(' character, e.g. a field descriptor like 'Ljava/lang/String;' or a raw class name was passed where a method descriptor like '(IJ)V' is required; also an empty/blank descriptor.","commonSituations":"A plugin or subclass of AbstractTypeFactoryProvider passing the wrong attribute (field descriptor instead of method descriptor); a malformed or corrupted class file whose method_descriptor attribute is damaged; hand-written URIs/fragments that omit the parameter list; version drift where an upstream library changed descriptor conventions.","solutions":["Verify the caller passes a method descriptor: it must match the pattern '^\\(.*\\).+' (parameters in parentheses followed by a return type).","If you have a field descriptor or class name, route it through writeSignature/type rendering instead of writeMethodSignature.","Re-extract or recompile the class file if the descriptor came from a corrupted artifact (javap -v to inspect method descriptors).","Print/log the descriptor at the call site to find which producer is supplying the malformed string, then fix that producer."],"exampleFix":"// before\nString descriptor = field.getDescriptor();\nwriteMethodSignature(sb, typeAccess, methodAccess, isInnerClass, name, name, descriptor);\n// after\nif (descriptor.indexOf('(') < 0) {\n    throw new IllegalArgumentException(\"Not a method descriptor: \" + descriptor);\n}\nwriteMethodSignature(sb, typeAccess, methodAccess, isInnerClass, name, name, descriptor);","handlingStrategy":"validation","validationCode":"// Method descriptors must look like '(args)return'\nboolean isMethodDescriptor(String d) {\n    if (d == null) return false;\n    int open = d.indexOf('(');\n    return open == 0 && d.indexOf(')', open) > 0;\n}","typeGuard":"boolean isFieldDescriptor(String d) {\n    return d != null && !d.isEmpty() && d.charAt(0) != '('; // route to writeSignature instead\n}","tryCatchPattern":"try {\n    writeMethodSignature(sb, typeAccess, methodAccess, isInnerClass, ctorName, methodName, descriptor);\n} catch (RuntimeException ex) {\n    if (ex.getMessage() != null && ex.getMessage().startsWith(\"Signature format exception:\")) {\n        sb.append(methodName).append(descriptor); // degrade to raw output\n    } else throw ex;\n}","preventionTips":["Confirm the attribute type before calling writeMethodSignature — only method descriptors start with '('","Route field descriptors and type names to the plain signature writer instead","Inspect suspicious artifacts with javap -v to confirm method_descriptor integrity","Add an early indexOf('(') check at call sites that accept both field and method descriptors"],"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"}