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
- Keep exactly one @Receives-annotated parameter per method; declare a separate method for each signal
- Move additional signal handling into other bean methods, each with a single @Receives parameter
- 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
- One @Receives parameter per method - one method per signal
- Review signatures when copy-pasting receiver methods
- Remember additional (non-@Receives) parameters must be injectable beans
- Run the build early; this fails at deployment, not runtime
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
- A receiver method must not be private:
- A receiver method must not be static:
- @CachedResults class must be an interface or declare a no-ar
- Not possible to define the scope %s for the REST client %s
- %s execution model is not supported: %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a280f660687d6773.
Report an issue: GitHub.