clojure/clojure · error · IllegalArgumentException

Invalid descriptor

Error message

Invalid descriptor: ${descriptor}

What it means

In getAbstractTypeFromDescriptor, if the very first character of the descriptor at the given offset is not one of the expected type-kind characters (primitive letter, '[', or 'L'), the descriptor is invalid for a verification type and IllegalArgumentException is thrown with the full remaining descriptor string. This is the outer (top-level) variant of the invalid-fragment check.

Solutions

  1. Fix the descriptor to a valid type descriptor (primitive letter, array '[...', or 'L...;').
  2. Ensure you pass a type descriptor, not a method descriptor or signature string.
  3. Correct offset computations so the substring starts at a real type character.
  4. Validate generated bytecode with CheckClassAdapter during development.

Example fix

// before
frame.abstractType(0, "(I)V"); // method descriptor by mistake
// after
frame.abstractType(0, "I");
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidTypeDescriptor(String d) {
  if (d == null || d.isEmpty()) return false;
  char c = d.charAt(0);
  if ("BCDFIJSZ".indexOf(c) >= 0) return d.length() == 1;
  if (c == '[') return isValidTypeDescriptor(d.substring(1));
  return c == 'L' && d.endsWith(";");
}
// call before passing into Frame/analyzer

Try / catch

try {
  frame.abstractType(offset, descriptor);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Invalid descriptor")) {
    log.error("Expected a type descriptor, got: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Frame abstractType/getAbstractTypeFromApiFormat with a descriptor starting with an illegal character, e.g. "x" or a method/signature string mistakenly passed where a type descriptor is expected.

Common situations: Passing a method descriptor like (I)V or a generic signature where a field/type descriptor is required; malformed locally generated bytecode being verified; off-by-one offsets into the descriptor buffer.

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 clojure/clojure@f3b143341d (2026-09-09). Data as JSON: /api/errors/523a8099044c9922. Report an issue: GitHub.

Appendix: source

Thrown at src/jvm/clojure/asm/Frame.java:383

            typeValue = FLOAT;
            break;
          case 'J':
            typeValue = LONG;
            break;
          case 'D':
            typeValue = DOUBLE;
            break;
          case 'L':
            internalName = buffer.substring(elementDescriptorOffset + 1, buffer.length() - 1);
            typeValue = REFERENCE_KIND | symbolTable.addType(internalName);
            break;
          default:
            throw new IllegalArgumentException(
                    "Invalid descriptor fragment: " + buffer.substring(elementDescriptorOffset));
        }
        return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue;
      default:
        throw new IllegalArgumentException("Invalid descriptor: " + buffer.substring(offset));
    }
  }

  // -----------------------------------------------------------------------------------------------
  // Methods related to the input frame
  // -----------------------------------------------------------------------------------------------

  /**
   * Sets the input frame from the given method description. This method is used to initialize the
   * first frame of a method, which is implicit (i.e. not stored explicitly in the StackMapTable
   * attribute).
   *
   * @param symbolTable the type table to use to lookup and store type {@link Symbol}.
   * @param access the method's access flags.
   * @param descriptor the method descriptor.
   * @param maxLocals the maximum number of local variables of the method.
   */
  final void setInputFrameFromDescriptor(

View on GitHub (pinned to f3b143341d)