oracle/graal · error · IllegalArgumentException
Unsupported annotation error element: %s
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.
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)
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 member %s.%s does not match declared type %s
- 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
- Annotation class element type %s has no host class
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/5ca474c05b378dce.
Report an issue: GitHub.