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

  1. Verify the caller passes a method descriptor: it must match the pattern '^\(.*\).+' (parameters in parentheses followed by a return type).
  2. If you have a field descriptor or class name, route it through writeSignature/type rendering instead of writeMethodSignature.
  3. Re-extract or recompile the class file if the descriptor came from a corrupted artifact (javap -v to inspect method descriptors).
  4. 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

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.