oracle/graal · error · IllegalArgumentException
Unsupported annotation error element
Error message
Unsupported annotation error element: %s
What it means
While converting individual annotation element values to the JDK proxy's expected forms, HostAnnotationValueConverter handles the known error-element kinds (MissingType -> TypeNotPresentExceptionProxy, ElementTypeMismatch -> DeferredAnnotationTypeMismatchExceptionProxy) but throws on any other ErrorElement subclass. The JDK annotation handler can only defer errors via specific proxies, so unrecognized error payloads cannot be represented and are rejected.
Solutions
- Ensure the JVMCI provider only emits MissingType or ElementTypeMismatch error elements (or none).
- Filter ErrorElement-valued members (or replace with MissingType) before conversion if your consumer can tolerate their absence.
- Align the producer's ErrorElement vocabulary with the converter version you run against.
- If introducing a new ErrorElement kind, add a corresponding ExceptionProxy mapping in the converter first.
Example fix
// before: elements.put("value", new GenericErrorElement(...));
// after: elements.put("value", new MissingType(typeName, cause)); Defensive patterns
Strategy: validation
Validate before calling
Object v = elements.get(member);
if (v instanceof ErrorElement && !(v instanceof MissingType) && !(v instanceof ElementTypeMismatch)) {
// replace or drop the member before conversion
} Type guard
static boolean isSupportedErrorElement(Object v) { return v instanceof MissingType || v instanceof ElementTypeMismatch; } Try / catch
try { convertElement(member, target, value, fn); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported annotation error element")) { /* drop member or degrade gracefully */ } else throw e; } Prevention
- Only emit MissingType / ElementTypeMismatch error elements in custom JVMCI providers.
- Filter unknown ErrorElement payloads at the metadata boundary.
- Keep the ErrorElement vocabulary in sync with the converter version.
When it happens
Trigger: A JVMCI implementation (or replay data) puts an ErrorElement subclass other than MissingType/ElementTypeMismatch into an annotation's element map, and conversion of that member reaches annotationValueElementAsHostValue.
Common situations: Custom or experimental JVMCI providers introducing new ErrorElement kinds; deserialized/replayed annotation metadata containing legacy or future error markers; partial-classloading states recorded into snapshots.
Related errors
- Annotation class element type
- Annotation member . does not match declared type
- Annotation value type
- Annotation value type
- Annotation value type
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/5ca474c05b378dce.
Report an issue: GitHub.
Appendix: source
Thrown at compiler/src/jdk.graal.compiler.vmaccess/src/jdk/graal/compiler/vmaccess/HostAnnotationValueConverter.java:141
memberValues.put(memberName, annotationValueElementAsHostValue(member, member.getReturnType(), memberValue, typeToClass));
}
return annotationType.cast(AnnotationParser.annotationForMap(annotationType, memberValues));
}
/**
* Converts one JVMCI annotation element representation to the value expected by the JDK
* annotation invocation handler.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private static Object annotationValueElementAsHostValue(Method member, Class<?> targetType, Object value, Function<ResolvedJavaType, Class<?>> typeToClass) {
if (value instanceof MissingType missingType) {
return new TypeNotPresentExceptionProxy(missingType.getTypeName(), missingType.getCause());
}
if (value instanceof ElementTypeMismatch mismatch) {
return new DeferredAnnotationTypeMismatchExceptionProxy(member, mismatch.getFoundType());
}
if (value instanceof ErrorElement) {
throw new IllegalArgumentException("Unsupported annotation error element: " + value);
}
if (targetType.isArray()) {
Class<?> componentType = targetType.getComponentType();
List<?> elements = (List<?>) value;
Object array = Array.newInstance(componentType, elements.size());
for (int i = 0; i < elements.size(); i++) {
Object element = annotationValueElementAsHostValue(member, componentType, elements.get(i), typeToClass);
if (element instanceof ExceptionProxy) {
return element;
}
Array.set(array, i, element);
}
return array;
}
if (targetType == Class.class) {
ResolvedJavaType classType = (ResolvedJavaType) value;
Class<?> clazz = typeToClass.apply(classType);
if (clazz == null) {View on GitHub (pinned to a66e9ccd1d)