quarkusio/quarkus · error · IllegalStateException

A generated bean does not declare the delegate field: ${gene

Error message

A generated bean does not declare the delegate field: ${generatedBean}

What it means

Quarkus inspects generated beans implementing MutinyBean to find their 'delegate' field, which reveals the gRPC service interface. A generated bean without a delegate field indicates corrupted/outdated generated code or a version mismatch between the stub generator and Quarkus, so deployment fails defensively.

Source

Thrown at extensions/grpc/deployment/src/main/java/io/quarkus/grpc/deployment/GrpcServerProcessor.java:130

    @BuildStep
    void processGeneratedBeans(CombinedIndexBuildItem index, BuildProducer<AnnotationsTransformerBuildItem> transformers,
            BuildProducer<BindableServiceBuildItem> bindables,
            BuildProducer<DelegatingGrpcBeanBuildItem> delegatingBeans) {

        // generated bean class -> blocking methods
        Map<DotName, Set<String>> generatedBeans = new HashMap<>();
        // generated bean class -> virtual methods
        Map<DotName, Set<String>> virtuals = new HashMap<>();
        String[] excludedPackages = { "grpc.health.v1", "io.grpc.reflection" };

        // We need to transform the generated bean and register a bindable service if:
        // 1. there is a user-defined bean that implements the generated interface (injected delegate)
        // 2. there is no user-defined bean that extends the relevant impl bases (both mutiny and regular)
        for (ClassInfo generatedBean : index.getIndex().getKnownDirectImplementors(GrpcDotNames.MUTINY_BEAN)) {
            FieldInfo delegateField = generatedBean.field("delegate");
            if (delegateField == null) {
                throw new IllegalStateException("A generated bean does not declare the delegate field: " + generatedBean);
            }
            DotName serviceInterface = delegateField.type().name();
            Collection<ClassInfo> serviceCandidates = index.getIndex().getAllKnownImplementors(serviceInterface);
            if (serviceCandidates.isEmpty()) {
                // No user-defined bean that implements the generated interface
                continue;
            }
            ClassInfo userDefinedBean = null;
            for (ClassInfo candidate : serviceCandidates) {
                // The bean must be annotated with @GrpcService
                if (candidate.declaredAnnotation(GrpcDotNames.GRPC_SERVICE) != null) {
                    userDefinedBean = candidate;
                    break;
                }
            }
            if (userDefinedBean == null) {
                continue;
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Run a clean build: ./mvnw clean install
  2. Regenerate stubs with a gRPC codegen version matching your Quarkus version
  3. Remove hand-written classes implementing MutinyBean — let Quarkus generate them
  4. Check the generated bean class under target/generated-sources for the delegate field

Example fix

// before (hand-written)
class GreeterBean implements MutinyBean<Greeter> { ... }

// after: delete the class and rely on Quarkus-generated GreeterBean
Defensive patterns

Strategy: validation

Validate before calling

# before building, regenerate everything cleanly
./mvnw clean install -DskipTests && ls target/generated-sources/protobuf/

Prevention

When it happens

Trigger: A class implementing io.quarkus.grpc.runtime.MutinyBean (or the MutinyBean dot name) is indexed but declares no field named 'delegate' during processGeneratedBeans.

Common situations: Stale target/classes from an older Quarkus version; hand-written class implementing MutinyBean; mismatch between grpc codegen plugin version and Quarkus version; incremental build corruption.

Related errors


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