quarkusio/quarkus · error · IllegalStateException

A receiver method must have exactly one parameter annotated

Error message

A receiver method must have exactly one parameter annotated with @Receives: ${methodDesc}

What it means

At Quarkus build time, the signals extension scans bean classes for signal receiver methods - methods with exactly one parameter annotated @Receives (e.g. @Receives SIGINT). If such a method has two or more parameters annotated @Receives, build fails with this IllegalStateException naming the method.

Source

Thrown at extensions/signals/deployment/src/main/java/io/quarkus/signals/deployment/SignalsProcessor.java:135

            ClassInfo beanClass = bean.getTarget().get().asClass();
            if (!hasReceiverInHierarchy(beanClass, classesWithReceivers, index)) {
                continue;
            }
            // Walk the class hierarchy; methods seen in subclasses override those from superclasses
            Set<MethodSignatureKey> seenMethods = new HashSet<>();
            ClassInfo current = beanClass;
            while (current != null) {
                for (MethodInfo method : current.methods()) {
                    if (method.isSynthetic() || method.isConstructor()) {
                        continue;
                    }
                    List<MethodParameterInfo> params = method.parameters();
                    MethodParameterInfo signalParam = null;
                    if (!params.isEmpty()) {
                        for (MethodParameterInfo param : params) {
                            if (param.hasDeclaredAnnotation(DotNames.RECEIVES)) {
                                if (signalParam != null) {
                                    throw new IllegalStateException(
                                            "A receiver method must have exactly one parameter annotated with @Receives: "
                                                    + methodDesc(method));
                                }
                                signalParam = param;
                            }
                        }
                    }
                    if (!seenMethods.add(method.signatureKey())) {
                        // Overridden by a subclass
                        continue;
                    }
                    if (signalParam != null) {
                        if (Modifier.isPrivate(method.flags())) {
                            throw new IllegalStateException(
                                    "A receiver method must not be private: " + methodDesc(method));
                        }
                        if (Modifier.isStatic(method.flags())) {
                            throw new IllegalStateException(

View on GitHub (pinned to e1c734241f)

Solutions

  1. Keep exactly one @Receives-annotated parameter per method; declare a separate method for each signal
  2. Move additional signal handling into other bean methods, each with a single @Receives parameter
  3. Non-signal parameters are allowed but must be resolvable beans (they use argument lookup) - only one may carry @Receives

Example fix

// before
void onSignal(@Receives Signal sigint, @Receives Signal sigterm) {...}
// after
void onSigint(@Receives Signal sigint) {...}
void onSigterm(@Receives Signal sigterm) {...}
Defensive patterns

Strategy: validation

Validate before calling

// Audit receiver methods before build: each must have exactly one @Receives parameter
// grep -rn "@Receives" src/main/java | check enclosing signatures

Prevention

When it happens

Trigger: Declaring a method like void handle(@Receives Signal a, @Receives Signal b) in a CDI bean; the SignalsProcessor.collectReceivers build step detects the second @Receives-annotated parameter during deployment.

Common situations: Developers expecting a receiver method to observe multiple signals simultaneously and annotating several parameters; copy-paste of a receiver signature then adding another @Receives param; misunderstanding that one method handles one signal.

Related errors


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