quarkusio/quarkus · error · ConfigurationException
The method `${method}` is using `@Keyed` but the annotated p
Error message
The method `${method}` is using `@Keyed` but the annotated parameter is not a `KeyedMulti` What it means
@Keyed is only valid on a parameter whose type is a parameterized KeyedMulti<K, V>. At build time, handleKeyedMulti checks the annotated parameter's type; if it is any other type, the build fails with this ConfigurationException.
Source
Thrown at extensions/smallrye-reactive-messaging/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/deployment/QuarkusMediatorConfigurationUtil.java:286
}
return configuration;
}
private static void handleKeyedMulti(MethodInfo methodInfo,
RecorderContext recorderContext, QuarkusMediatorConfiguration configuration) {
if (methodInfo.parametersCount() == 1) { // @Keyed can only be used with a single parameter, a keyed multi
var info = methodInfo.parameters().get(0);
var annotation = info.annotation(ReactiveMessagingDotNames.KEYED);
if (annotation != null) {
// Make sure we have a keyed multi and an incoming.
if (methodInfo.annotation(INCOMING) == null && methodInfo.annotation(INCOMINGS) == null) {
throw new ConfigurationException(
"The method `" + methodInfo.name() + "` is using `@Keyed` but is not annotated with `@Incoming`");
}
if (info.type().kind() != Type.Kind.PARAMETERIZED_TYPE
|| !info.type().asParameterizedType().name().equals(ReactiveMessagingDotNames.KEYED_MULTI)) {
throw new ConfigurationException("The method `" + methodInfo.name()
+ "` is using `@Keyed` but the annotated parameter is not a `KeyedMulti`");
}
var extractor = (Class<? extends KeyValueExtractor>) recorderContext
.classProxy(annotation.value().asClass().name().toString());
configuration.setKeyed(extractor);
}
if (info.type().kind() == Type.Kind.PARAMETERIZED_TYPE
&& info.type().asParameterizedType().name().equals(ReactiveMessagingDotNames.KEYED_MULTI)) {
var args = info.type().asParameterizedType().arguments();
configuration.setKeyType(recorderContext.classProxy(args.get(0).name().toString()));
configuration.setValueType(recorderContext.classProxy(args.get(1).name().toString()));
}
}
}
// TODO: avoid hard coding CompletionStage handling
private static Type determineReturnTypeOfSuspendMethod(MethodInfo methodInfo) {
Type lastParamType = methodInfo.parameterType(methodInfo.parametersCount() - 1);View on GitHub (pinned to e1c734241f)
Solutions
- Change the annotated parameter type to KeyedMulti<K, V> with explicit type parameters, e.g. KeyedMulti<String, Order>
- Remove @Keyed if the stream is not a keyed multi
- Ensure the first parameter (the @Keyed one) is the KeyedMulti itself per the API contract
Example fix
// before
void process(@Keyed Multi<Order> orders) { ... }
// after
@Incoming("orders")
void process(@Keyed KeyedMulti<String, Order> orders) { ... } Defensive patterns
Strategy: validation
Validate before calling
Parameter p = method.getParameters()[0];
if (p.isAnnotationPresent(Keyed.class)
&& !(p.getType() instanceof ParameterizedType
&& ((ParameterizedType) p.getType()).getRawType() == KeyedMulti.class)) {
throw new IllegalStateException("@Keyed parameter must be KeyedMulti<K,V>");
} Prevention
- Always declare KeyedMulti with explicit type parameters: KeyedMulti<String, Payload>
- Keep the @Keyed annotation on the KeyedMulti parameter itself
- Review parameter types when migrating from Multi-based keyed patterns
When it happens
Trigger: Using @Keyed on a parameter typed Multi<V>, List<V>, a plain type, or a raw KeyedMulti without type parameters instead of KeyedMulti<String, Payload> (or another key type).
Common situations: Migrating from a Multi-based keyed pattern to KeyedMulti; forgetting type arguments on KeyedMulti; copy-pasting @Keyed onto the wrong parameter.
Related errors
- The method `${method}` is using `@RunOnVirtualThread` but ex
- The method `${method}` is using `@Keyed` but is not annotate
- @ExactlyOnce on method ${methodName} must return a value to
- A generic type is not allowed here; try creating a subclass
- Unsupported wildcard type: ${wildcard}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/eaf0dd6b941be59a.
Report an issue: GitHub.