quarkusio/quarkus · error · IllegalStateException

AnnotationInstance ${instance} is an invalid target. Only Cl

Error message

AnnotationInstance ${instance} is an invalid target. Only Class targets are supported

What it means

The Spring DI extension derives bean names from stereotype annotations (@Component, @Service, @Repository). This method expects the annotation instance to target a class; when the target is anything else (method, field, parameter), the build fails with this IllegalStateException. Only class-level stereotype placement is supported for bean-name derivation.

Source

Thrown at extensions/spring-di/deployment/src/main/java/io/quarkus/spring/di/deployment/SpringDIProcessor.java:502

        // in Spring List<SomeBean> means that all instances of SomeBean should be injected
        List<Type> parameters = methodInfo.parameterTypes();
        for (int i = 0; i < parameters.size(); i++) {
            Type parameter = parameters.get(i);
            if (parameter.name().equals(DotNames.LIST)) {
                annotationsToAdd.add(create(
                        QUARKUS_ALL_ANNOTATION,
                        MethodParameterInfo.create(methodInfo, (short) i),
                        Collections.emptyList()));
            }
        }
    }

    /**
     * Meant to be called with instances of @Component, @Service, @Repository
     */
    private String getBeanNameFromStereotypeInstance(AnnotationInstance annotationInstance) {
        if (annotationInstance.target().kind() != AnnotationTarget.Kind.CLASS) {
            throw new IllegalStateException(
                    "AnnotationInstance " + annotationInstance + " is an invalid target. Only Class targets are supported");
        }
        final AnnotationValue value = annotationInstance.value();
        if ((value == null) || value.asString().isEmpty()) {
            return getDefaultBeanNameFromClass(annotationInstance.target().asClass().name().toString());
        } else {
            return value.asString();
        }
    }

    /**
     * Meant to be called with instances of @Bean
     */
    private String getBeanNameFromBeanInstance(AnnotationInstance annotationInstance) {
        if (annotationInstance.target().kind() != AnnotationTarget.Kind.METHOD) {
            throw new IllegalStateException(
                    "AnnotationInstance " + annotationInstance + " is an invalid target. Only Method targets are supported");
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move @Component/@Service/@Repository to class level only; use @Bean methods in a @Configuration class for method-level registration
  2. If @Repository is used on an exception class for Spring exception translation, drop it or guard it — Quarkus doesn't need it
  3. Refactor custom composed annotations so stereotype annotations are only @Target(TYPE)
  4. Check index results for stray stereotype annotations on non-class members and remove them

Example fix

// before
public class Config {
    @Component
    private MyService service; // invalid target
}

// after
@Component
public class MyService { }
Defensive patterns

Strategy: validation

Validate before calling

// Guard custom annotations to class targets only:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface MyService {}
// and never place @Component/@Service/@Repository on fields or parameters

Prevention

When it happens

Trigger: @Component/@Service/@Repository applied to a non-class target — e.g., a field or method parameter — via a meta-annotation or custom composed annotation that the index resolves with a non-CLASS target.

Common situations: Copy-pasting @Component onto a field; custom meta-annotations inadvertently exposing stereotype annotations to non-class elements; Spring's non-component usages (e.g., @Repository on exceptions for exception translation) being picked up by the DI processor.

Related errors


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