oracle/graal · error · IllegalArgumentException
Annotation member %s.%s does not match declared type %s
Error message
Annotation member %s.%s does not match declared type %s
What it means
AnnotationValueValidation.validateElements checks each explicit element of a JVMCI AnnotationValue against the declared member types of the corresponding annotation type; a member whose runtime value does not match its declared type (e.g. a String where an int/class/enum is declared, even recursively inside arrays) throws this with the annotation name, member name, and expected type. Per the javadoc, missing members and defaults are intentionally not checked — only present elements with the wrong kind of value.
Source
Thrown at compiler/src/jdk.graal.compiler.vmaccess/src/jdk/graal/compiler/vmaccess/AnnotationValueValidation.java:66
}
/**
* Validates each explicitly supplied, recognized element of {@code annotationValue} against
* the member type described by {@code annotationValueType}, recursively checking array
* elements. Error elements are accepted because they represent failures that must remain
* deferred until the affected annotation member is accessed. Missing members and defaults are
* not checked here; providers preserve missing required members and supply defaults while
* materializing the annotation proxy.
*
* @param annotationValue the annotation metadata containing the explicit elements
* @param annotationValueType the declared member types used for validation
* @throws IllegalArgumentException if an element does not match its declared member type
*/
public static void validateElements(AnnotationValue annotationValue, AnnotationValueType annotationValueType) {
for (Map.Entry<String, Object> entry : annotationValue.getElements().entrySet()) {
ResolvedJavaType memberType = annotationValueType.memberTypes().get(entry.getKey());
if (memberType != null && !matchesElementType(entry.getValue(), memberType)) {
throw new IllegalArgumentException("Annotation member " + annotationValue.getAnnotationType().toJavaName() + "." + entry.getKey() +
" does not match declared type " + memberType.toJavaName());
}
}
}
/**
* Determines whether a JVMCI annotation element representation matches its declared member
* type, recursively validating array elements.
*/
private static boolean matchesElementType(Object value, ResolvedJavaType expectedType) {
if (value == null) {
return false;
}
if (value instanceof ErrorElement) {
return true;
}
if (expectedType.isArray()) {
if (!(value instanceof List<?> elements)) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Fix the producer of the AnnotationValue so element values match declared member types (primitives boxed correctly, classes as ResolvedJavaType, enums as EnumElement, arrays as lists).
- If consuming foreign metadata, validate with this method early and reject/report the offending annotation before use.
- Align JVMCI/JDK versions between producer and consumer so member declarations agree.
- Log annotationValue.getAnnotationType().toJavaName() + member name at the failure site to pinpoint the bad member.
Example fix
// before: elements.put("phase", "Phase plat forming"); // String for enum member
// after: elements.put("phase", new EnumElement(CompilationPhasePhase, "PLATFORMING")); Defensive patterns
Strategy: validation
Validate before calling
for (Map.Entry<String, Object> e : annotationValue.getElements().entrySet()) {
ResolvedJavaType declared = annotationValueType.memberTypes().get(e.getKey());
if (declared != null && !AnnotationValueValidation.matchesElementTypePublic(e.getValue(), declared)) {
// report and drop the bad member before downstream conversion
}
} Try / catch
try { AnnotationValueValidation.validateElements(av, avt); } catch (IllegalArgumentException e) { /* log av.getAnnotationType().toJavaName() + member and reject the annotation */ } Prevention
- Validate element maps at the boundary where foreign metadata enters your system.
- Keep JVMCI producer and consumer versions aligned.
- Remember missing members/defaults are not validated — only present, mismatched ones.
When it happens
Trigger: A JVMCI-returned annotation whose element map contains a value of an incompatible Java type for its declared member — class-valued member holding a String, array member holding a non-list, enum member holding a wrong-type constant — reaching validateElements. The recursive matchesElementType check also fails on null values or arrays containing mismatched elements.
Common situations: Hand-constructed or deserialized AnnotationValue metadata (e.g. from a snapshot/replay system or a custom JVMCI implementation) where element maps were built loosely; version skew where an annotation's members changed type between JVMCI versions.
Related errors
- Annotation value type %s has no host class
- Annotation value type %s is not an annotation interface
- Annotation value type %s is not assignable to %s
- Unsupported annotation error element: %s
- Annotation class element type %s has no host class
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/7e0f8d335ac77e44.
Report an issue: GitHub.