{"record":{"id":"523a8099044c9922","repo":"clojure/clojure","slug":"invalid-descriptor-descriptor","errorCode":null,"errorMessage":"Invalid descriptor: ${descriptor}","messagePattern":"Invalid descriptor: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/asm/Frame.java","lineNumber":383,"sourceCode":"            typeValue = FLOAT;\n            break;\n          case 'J':\n            typeValue = LONG;\n            break;\n          case 'D':\n            typeValue = DOUBLE;\n            break;\n          case 'L':\n            internalName = buffer.substring(elementDescriptorOffset + 1, buffer.length() - 1);\n            typeValue = REFERENCE_KIND | symbolTable.addType(internalName);\n            break;\n          default:\n            throw new IllegalArgumentException(\n                    \"Invalid descriptor fragment: \" + buffer.substring(elementDescriptorOffset));\n        }\n        return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue;\n      default:\n        throw new IllegalArgumentException(\"Invalid descriptor: \" + buffer.substring(offset));\n    }\n  }\n\n  // -----------------------------------------------------------------------------------------------\n  // Methods related to the input frame\n  // -----------------------------------------------------------------------------------------------\n\n  /**\n   * Sets the input frame from the given method description. This method is used to initialize the\n   * first frame of a method, which is implicit (i.e. not stored explicitly in the StackMapTable\n   * attribute).\n   *\n   * @param symbolTable the type table to use to lookup and store type {@link Symbol}.\n   * @param access the method's access flags.\n   * @param descriptor the method descriptor.\n   * @param maxLocals the maximum number of local variables of the method.\n   */\n  final void setInputFrameFromDescriptor(","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/asm/Frame.java#L365-L401","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the descriptor to a valid type descriptor (primitive letter, array '[...', or 'L...;').","Ensure you pass a type descriptor, not a method descriptor or signature string.","Correct offset computations so the substring starts at a real type character.","Validate generated bytecode with CheckClassAdapter during development."],"exampleFix":"// before\nframe.abstractType(0, \"(I)V\"); // method descriptor by mistake\n// after\nframe.abstractType(0, \"I\");","handlingStrategy":"validation","validationCode":"static boolean isValidTypeDescriptor(String d) {\n  if (d == null || d.isEmpty()) return false;\n  char c = d.charAt(0);\n  if (\"BCDFIJSZ\".indexOf(c) >= 0) return d.length() == 1;\n  if (c == '[') return isValidTypeDescriptor(d.substring(1));\n  return c == 'L' && d.endsWith(\";\");\n}\n// call before passing into Frame/analyzer","typeGuard":null,"tryCatchPattern":"try {\n  frame.abstractType(offset, descriptor);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid descriptor\")) {\n    log.error(\"Expected a type descriptor, got: \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Pass type descriptors (I, Ljava/lang/String;), never method descriptors like (I)V.","Build descriptors via Type.getDescriptor rather than string concatenation.","Verify bytecode with CheckClassAdapter during development.","Double-check buffer offsets when slicing descriptor strings."],"tags":["java","asm","bytecode","descriptor","dataflow"],"backgroundTag":"invalid-argument-format","analyzedSha":"f3b143341d6efc6428b523b2eaa099a6cc99156e","analyzedAt":"2026-09-09T12:04:58.961Z","contentChangedAt":"2026-09-09T12:04:58.961Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}