{"record":{"id":"6edfdfae4aaae65d","repo":"oracle/graal","slug":"annotation-class-element-type-s-has-no-host-class","errorCode":null,"errorMessage":"Annotation class element type %s has no host class","messagePattern":"Annotation class element type (.+?) has no host class","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.vmaccess/src/jdk/graal/compiler/vmaccess/HostAnnotationValueConverter.java","lineNumber":160,"sourceCode":"        }\n        if (targetType.isArray()) {\n            Class<?> componentType = targetType.getComponentType();\n            List<?> elements = (List<?>) value;\n            Object array = Array.newInstance(componentType, elements.size());\n            for (int i = 0; i < elements.size(); i++) {\n                Object element = annotationValueElementAsHostValue(member, componentType, elements.get(i), typeToClass);\n                if (element instanceof ExceptionProxy) {\n                    return element;\n                }\n                Array.set(array, i, element);\n            }\n            return array;\n        }\n        if (targetType == Class.class) {\n            ResolvedJavaType classType = (ResolvedJavaType) value;\n            Class<?> clazz = typeToClass.apply(classType);\n            if (clazz == null) {\n                throw new IllegalArgumentException(\"Annotation class element type \" + classType.toJavaName() + \" has no host class\");\n            }\n            return clazz;\n        }\n        if (targetType.isEnum()) {\n            EnumElement enumElement = (EnumElement) value;\n            Class<?> enumType = typeToClass.apply(enumElement.enumType);\n            if (enumType == null) {\n                throw new IllegalArgumentException(\"Annotation enum element type \" + enumElement.enumType.toJavaName() + \" has no host class\");\n            }\n            if (enumType != targetType) {\n                throw new IllegalArgumentException(\"Unexpected enum type: \" + enumType.getName());\n            }\n            try {\n                return Enum.valueOf((Class<? extends Enum>) enumType.asSubclass(Enum.class), enumElement.name);\n            } catch (IllegalArgumentException e) {\n                return new EnumConstantNotPresentExceptionProxy((Class<? extends Enum<?>>) enumType, enumElement.name);\n            }\n        }","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.vmaccess/src/jdk/graal/compiler/vmaccess/HostAnnotationValueConverter.java#L142-L178","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nFunction<ResolvedJavaType, Class<?>> fn = t -> bootLoader.get(t.toJavaName()); // null for app classes\n// after\nFunction<ResolvedJavaType, Class<?>> fn = t -> {\n    Class<?> c = bootLoader.get(t.toJavaName());\n    return c != null ? c : Class.forName(t.toJavaName(), false, Thread.currentThread().getContextClassLoader());\n};","handlingStrategy":"validation","validationCode":"if (targetType == Class.class) {\n    ResolvedJavaType ct = (ResolvedJavaType) value;\n    if (typeToClass.apply(ct) == null) { /* pre-resolve or drop this member before toAnnotation */ }\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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."],"tags":["graalvm","jvmci","annotations","classloading"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}