java-decompiler/jd-gui · error · RuntimeException
Signature format exception: '${descriptor}'
Error message
Signature format exception: '${descriptor}' What it means
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.
Source
Thrown at services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java:213
sb.append("{...}");
} else {
boolean isAConstructor = methodName.equals("<init>");
if (isAConstructor) {
sb.append(constructorName);
} else {
sb.append(methodName);
}
// Skip generics
int length = descriptor.length();
int index = 0;
while ((index < length) && (descriptor.charAt(index) != '('))
index++;
if (descriptor.charAt(index) != '(') {
throw new RuntimeException("Signature format exception: '" + descriptor + "'");
}
sb.append('(');
// pass '('
index++;
if (descriptor.charAt(index) != ')') {
if (isAConstructor && isInnerClass && ((typeAccess & Type.FLAG_STATIC) == 0)) {
// Skip first parameter
int lengthBackup = sb.length();
index = writeSignature(sb, descriptor, length, index, false);
sb.setLength(lengthBackup);
}
if (descriptor.charAt(index) != ')') {
int varargsParameterIndex;
View on GitHub (pinned to b3c1ced04e)
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.
Example fix
// before
String descriptor = field.getDescriptor();
writeMethodSignature(sb, typeAccess, methodAccess, isInnerClass, name, name, descriptor);
// after
if (descriptor.indexOf('(') < 0) {
throw new IllegalArgumentException("Not a method descriptor: " + descriptor);
}
writeMethodSignature(sb, typeAccess, methodAccess, isInnerClass, name, name, descriptor); Defensive patterns
Strategy: validation
Validate before calling
// Method descriptors must look like '(args)return'
boolean isMethodDescriptor(String d) {
if (d == null) return false;
int open = d.indexOf('(');
return open == 0 && d.indexOf(')', open) > 0;
} Type guard
boolean isFieldDescriptor(String d) {
return d != null && !d.isEmpty() && d.charAt(0) != '('; // route to writeSignature instead
} Try / catch
try {
writeMethodSignature(sb, typeAccess, methodAccess, isInnerClass, ctorName, methodName, descriptor);
} catch (RuntimeException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Signature format exception:")) {
sb.append(methodName).append(descriptor); // degrade to raw output
} else throw ex;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of java-decompiler/jd-gui@b3c1ced04e (2026-09-06).
Data as JSON: /api/errors/63ca2246d3b52086.
Report an issue: GitHub.