quarkusio/quarkus · error · IllegalStateException

${clientAnnotation} may not be declared at ${target}

Error message

${clientAnnotation} may not be declared at ${target}

What it means

@GrpcClient is only allowed on fields and method parameters (@Target({FIELD, PARAMETER})). If the annotation instance is found on any other target (class, method, etc.), the deployment throws this IllegalStateException. This is a defensive check that should be unreachable in normal Java code.

Source

Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcClientProcessor.java:174

            String clientName;
            AnnotationValue clientNameValue = clientAnnotation.value();
            if (clientNameValue == null || clientNameValue.asString().equals(GrpcClient.ELEMENT_NAME)) {
                // Determine the service name from the annotated element
                if (clientAnnotation.target().kind() == Kind.FIELD) {
                    clientName = clientAnnotation.target().asField().name();
                } else if (clientAnnotation.target().kind() == Kind.METHOD_PARAMETER) {
                    MethodParameterInfo param = clientAnnotation.target().asMethodParameter();
                    clientName = param.method().parameterName(param.position());
                    if (clientName == null) {
                        throw new DeploymentException("Unable to determine the client name from the parameter at position "
                                + param.position()
                                + " in method "
                                + param.method().declaringClass().name() + "#" + param.method().name()
                                + "() - compile the class with debug info enabled (-g) or parameter names recorded (-parameters), or use GrpcClient#value() to specify the service name");
                    }
                } else {
                    // This should never happen because @GrpcClient has @Target({ FIELD, PARAMETER })
                    throw new IllegalStateException(clientAnnotation + " may not be declared at " + clientAnnotation.target());
                }
            } else {
                clientName = clientNameValue.asString();
            }

            if (clientName.trim().isEmpty()) {
                throw new DeploymentException(
                        "Invalid @GrpcClient `" + injectionPoint.getTargetInfo() + "` - client name cannot be empty");
            }

            GrpcClientBuildItem item;
            if (items.containsKey(clientName)) {
                item = items.get(clientName);
            } else {
                item = new GrpcClientBuildItem(clientName);
                items.put(clientName, item);
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move @GrpcClient onto a field or a method parameter
  2. If generated by a tool, fix the generator to respect @GrpcClient's @Target
  3. Ensure no custom annotation transformer re-targets @GrpcClient

Example fix

// before
@GrpcClient("svc")
public class MyService { ... }

// after
public class MyService {
    @Inject @GrpcClient("svc") Greeter greeter;
}
Defensive patterns

Strategy: validation

Validate before calling

// only place @GrpcClient on fields or method parameters
@Target({ElementType.FIELD, ElementType.PARAMETER}) // existing definition — respect it
class MyBean { @Inject @GrpcClient("svc") Greeter greeter; }

Prevention

When it happens

Trigger: An @GrpcClient annotation instance whose reflection target is neither a field nor a method parameter is processed during injection-point discovery — practically only via bytecode-generated/transformed classes or exotic annotation processing.

Common situations: Code-generation or bytecode tooling that misplaced the annotation; custom CDI extensions registering synthetic annotated members; manually built annotation instances in build steps.

Related errors


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