oracle/graal · error · IllegalArgumentException
Annotation class element type %s has no host class
Error message
Annotation class element type %s has no host class
What it means
When an annotation member is declared as Class (Class<?> value()), the converter takes the ResolvedJavaType element value and maps it through the caller's typeToClass function; if that returns null, this exception names the class type that could not be mapped. It is the element-level analogue of error 395 — the annotation itself resolved, but a class-valued member refers to a type with no host class.
Source
Thrown at compiler/src/jdk.graal.compiler.vmaccess/src/jdk/graal/compiler/vmaccess/HostAnnotationValueConverter.java:160
}
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) {
throw new IllegalArgumentException("Annotation class element type " + classType.toJavaName() + " has no host class");
}
return clazz;
}
if (targetType.isEnum()) {
EnumElement enumElement = (EnumElement) value;
Class<?> enumType = typeToClass.apply(enumElement.enumType);
if (enumType == null) {
throw new IllegalArgumentException("Annotation enum element type " + enumElement.enumType.toJavaName() + " has no host class");
}
if (enumType != targetType) {
throw new IllegalArgumentException("Unexpected enum type: " + enumType.getName());
}
try {
return Enum.valueOf((Class<? extends Enum>) enumType.asSubclass(Enum.class), enumElement.name);
} catch (IllegalArgumentException e) {
return new EnumConstantNotPresentExceptionProxy((Class<? extends Enum<?>>) enumType, enumElement.name);
}
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Make typeToClass able to resolve the named type (extend its loader/search set; put the missing class on the classpath).
- For replay scenarios, record/provide host classes for all types referenced by class-valued annotation members.
- If unmappable class members are acceptable in your use, pre-scan elements and substitute a TypeNotPresentExceptionProxy-like deferral instead of converting.
- Log classType.toJavaName() from the catch site to identify exactly which class is missing.
Example fix
// before
Function<ResolvedJavaType, Class<?>> fn = t -> bootLoader.get(t.toJavaName()); // null for app classes
// after
Function<ResolvedJavaType, Class<?>> fn = t -> {
Class<?> c = bootLoader.get(t.toJavaName());
return c != null ? c : Class.forName(t.toJavaName(), false, Thread.currentThread().getContextClassLoader());
}; Defensive patterns
Strategy: validation
Validate before calling
if (targetType == Class.class) {
ResolvedJavaType ct = (ResolvedJavaType) value;
if (typeToClass.apply(ct) == null) { /* pre-resolve or drop this member before toAnnotation */ }
} Try / catch
try { toAnnotation(av, Expected.class, fn); } catch (IllegalArgumentException e) { if (e.getMessage().contains("class element type") && e.getMessage().contains("no host class")) { /* widen fn to reach the named class */ } else throw e; } Prevention
- Give typeToClass a broad fallback (Class.forName with context loader).
- For replay, record host classes for every type named by class-valued members.
- Log the failing toJavaName() to identify the missing class quickly.
When it happens
Trigger: Calling toAnnotation for an annotation like @ClassList({Foo.class}) where Foo (or a type it references) is not resolvable by the supplied typeToClass — e.g. it belongs to a classloader the lookup cannot reach, or was never recorded in replay metadata.
Common situations: Snapshot/replay of compilations referencing application classes not on the replay classpath; isolated/embedded classloading where annotation members point into the guest namespace; pruned deployment jars missing classes referenced only by annotation members.
Related errors
- Annotation value type %s has no host class
- Annotation value type %s is not an annotation interface
- Annotation member %s.%s does not match declared type %s
- Annotation value type %s is not assignable to %s
- Unsupported annotation error element: %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/6edfdfae4aaae65d.
Report an issue: GitHub.