quarkusio/quarkus · error · IllegalArgumentException

Not an annotation:

Error message

Not an annotation: 

What it means

Annotations.annotationType() resolves the annotation interface (Class) for a given object (typically a AnnotationLiteral or annotation instance). It walks the class and its interfaces looking for one that isInterface() && isAnnotation(); if none is found it throws IllegalArgumentException. This guards APIs that require a real annotation instance.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Annotations.java:251

    @SuppressWarnings("unchecked")
    private static Class<? extends Annotation> annotationType(Annotation annotation) {
        Class<? extends Annotation> annotationType = null;

        Queue<Class<?>> candidates = new ArrayDeque<>();
        candidates.add(annotation.getClass());
        while (!candidates.isEmpty()) {
            Class<?> candidate = candidates.remove();

            if (candidate.isAnnotation()) {
                annotationType = (Class<? extends Annotation>) candidate;
                break;
            }

            Collections.addAll(candidates, candidate.getInterfaces());
        }

        if (annotationType == null) {
            throw new IllegalArgumentException("Not an annotation: " + annotation);
        }

        return annotationType;
    }

    private static <A extends Annotation> org.jboss.jandex.AnnotationValue[] jandexAnnotationValues(
            Class<A> annotationType, A annotationInstance) {
        List<org.jboss.jandex.AnnotationValue> result = new ArrayList<>();
        for (Method member : annotationType.getDeclaredMethods()) {
            try {
                // annotation types do not necessarily have to be public (if the annotation type
                // and the build compatible extension class reside in the same package)
                if (!member.canAccess(annotationInstance)) {
                    member.setAccessible(true);
                }
                result.add(jandexAnnotationValue(member.getName(), member.invoke(annotationInstance)));
            } catch (ReflectiveOperationException e) {
                throw new RuntimeException(e);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Pass a proper jakarta.enterprise.util.AnnotationLiteral subclass or a real annotation instance
  2. Verify the argument's class actually implements java.lang.annotation.Annotation at runtime
  3. Check that custom literal classes extend AnnotationLiteral<AnnotationType> with the correct type parameter
  4. If using proxies/bytecode enhancement, ensure the annotation interface is retained

Example fix

// before
Object q = new MyQualifierImpl(); // not an Annotation
// after
MyQualifier q = new MyQualifier() { /* AnnotationLiteral impl */ };
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(candidate instanceof Annotation a)) throw new IllegalArgumentException("Not an annotation");
if (!a.annotationType().isAnnotation()) throw new IllegalArgumentException("No annotation interface");

Type guard

static boolean isAnnotationInstance(Object o) {
    return o instanceof Annotation a && a.annotationType().isAnnotation();
}

Try / catch

try { Class<? extends Annotation> t = Annotations.annotationType(ann); }
catch (IllegalArgumentException e) { log.error("Not an annotation: pass AnnotationLiteral subclass", e); }

Prevention

When it happens

Trigger: Calling an Arc API with an object that is not an annotation or annotation literal whose class hierarchy contains an annotation interface — e.g. passing a plain Object/subclass to a method expecting an annotation or AnnotationLiteral, or a literal class that fails to be recognized as implementing Annotation.

Common situations: Hand-rolled 'annotation literal' classes that extend the wrong base or are generated by bytecode manipulation; passing a qualifier instance of the wrong type; reflection-created proxies losing annotation marker interfaces.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7911680c21ce91b8. Report an issue: GitHub.