projectlombok/lombok · error · ClassCastException
Not an annotation type
Error message
Not an annotation type: <target>
What it means
SpiLoadUtil.findAnnotationHelper resolves an annotation class from a service-loader config value, which may be a Class or a Field. If the resolved target is neither null nor a Class assignable to java.lang.annotation.Annotation, it throws this ClassCastException. It means the configured type is not an annotation type as required.
Solutions
- Check the configured value at <target>: it must be the fully-qualified name of an @interface (annotation type), not a class or enum.
- Fix the FQN in the service/config registration to reference the annotation itself (e.g. lombok.foo.HandlerAnnotation), not its processor.
- Verify the referenced type still extends java.lang.annotation.Annotation after refactors; update stale names.
- If the target may legitimately be absent, note that findAnnotationHelper returns null (not an exception) when the field value is null — only non-Class, non-Annotation values throw.
Example fix
// before (config value points at a class, not an annotation) lombok.launch.AnnotationProcessorHider$AstModificationNotifier -> ClassCastException // after (point at the annotation type) lombok.extern.java.Log
Defensive patterns
Strategy: validation
Validate before calling
Object target = ...; // resolved config value
if (target instanceof Class<?> c && !java.lang.annotation.Annotation.class.isAssignableFrom(c))
throw new IllegalStateException("Configured type is not an annotation: " + c.getName()); Type guard
static boolean isAnnotationType(Object o) {
return o instanceof Class<?> c && java.lang.annotation.Annotation.class.isAssignableFrom(c);
} Try / catch
try {
Class<? extends Annotation> ann = findAnnotationClass(field, loader);
} catch (ClassCastException e) {
if (e.getMessage().startsWith("Not an annotation type:")) {
// fix the FQN in the service config to point at the @interface
} else throw e;
} Prevention
- Register the annotation type (@interface FQN), not the handler/processor class.
- After renaming annotations, grep service/config files for stale names.
- Validate with Annotation.class.isAssignableFrom before resolving.
- Keep annotation and processor FQNs distinct in config to avoid mixups.
When it happens
Trigger: findAnnotationClass -> findAnnotationHelper with a registration whose value is a Class that does not extend Annotation (e.g. a plain class, interface, or enum listed where an annotation is expected) — typical of a typo'd FQN in a service/annotation-map config or a class placed under the wrong registration key.
Common situations: Typing a handler class name where the annotation FQN should go; renaming/refactoring an annotation so the config still points at the old non-annotation class; registering the annotation's processor class instead of the annotation itself.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- ${element} ${message}
- Expected a single value, but
- I/O problem during delombok
- @Delegate does not support recursion (delegating to a type…
- Cannot obtain canonical path to parent directory
AI-assisted analysis of projectlombok/lombok@6d6a3e9fec (2026-09-07).
Data as JSON: /api/errors/2d0520c2391dcd66.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/lombok/core/SpiLoadUtil.java:193
if (potential != null) return potential;
}
return null;
}
@SuppressWarnings("unchecked")
private static Class<? extends Annotation> findAnnotationHelper(Class<?> base, Type iface) {
if (iface instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType)iface;
if (!base.equals(p.getRawType())) return null;
Type target = p.getActualTypeArguments()[0];
if (target instanceof Class<?>) {
if (Annotation.class.isAssignableFrom((Class<?>) target)) {
return (Class<? extends Annotation>) target;
}
}
throw new ClassCastException("Not an annotation type: " + target);
}
return null;
}
}
View on GitHub (pinned to 6d6a3e9fec)