quarkusio/quarkus · error · RestClientDefinitionException
Duplicate ${annotationName} annotation for parameter: ${name
Error message
Duplicate ${annotationName} annotation for parameter: ${name} on ${target} What it means
MicroProfile REST Client parameter annotations like @QueryParam and @HeaderParam (and @PathParam/@CookieParam variants) are collected per method parameter. Each parameter may carry only one instance of a given annotation kind; putAllParamAnnotations uses the annotation's 'name' as a map key and throws RestClientDefinitionException when a duplicate name would overwrite existing data.
Source
Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/MicroProfileRestClientEnricher.java:361
Map<String, ParamData> methodLevelParamsByName = new HashMap<>();
AnnotationInstance methodLevelParam = method.annotation(clientParamAnnotation);
if (methodLevelParam != null) {
methodLevelParamsByName.put(methodLevelParam.value("name").asString(),
new ParamData(methodLevelParam, interfaceClass));
}
putAllParamAnnotations(methodLevelParamsByName, interfaceClass,
extractAnnotations(method.annotation(clientParamsAnnotation)), annotationName);
paramFillersByName.putAll(methodLevelParamsByName);
}
private void putAllParamAnnotations(Map<String, ParamData> paramMap, ClassInfo interfaceClass,
AnnotationInstance[] annotations, String annotationName) {
for (AnnotationInstance annotation : annotations) {
String name = annotation.value("name").asString();
if (paramMap.put(name, new ParamData(annotation, interfaceClass)) != null) {
throw new RestClientDefinitionException("Duplicate " + annotationName + " annotation for parameter: " + name +
" on " + annotation.target());
}
}
}
private void addParam(MethodInfo declaringMethod, MethodCreator methodCreator,
ParamData paramData, BuildProducer<GeneratedClassBuildItem> generatedClasses,
IndexView index, DotName clientParamAnnotation, String annotationName, String paramName,
Supplier<ResultHandle> existenceChecker,
BiConsumer<BytecodeCreator, ResultHandle> paramAdder) {
AnnotationInstance annotation = paramData.annotation;
ClassInfo declaringClass = paramData.definingClass;
ResultHandle isParamPresent = existenceChecker.get();
BytecodeCreator creator = methodCreator.ifTrue(isParamPresent).falseBranch();
String[] values = annotation.value().asStringArray();View on GitHub (pinned to e1c734241f)
Solutions
- Remove the duplicate annotation for that parameter — one @QueryParam("x") per parameter
- If both parent and child interfaces declare it, keep only one declaration or remove the override's duplicate
- Audit the interface named in 'on ${target}' for repeated annotation names
Example fix
// before
void get(@QueryParam("q") String q, @QueryParam("q") String q2); // duplicate 'q'
// after
void get(@QueryParam("q") String q, @QueryParam("q2") String q2); Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (Annotation a : param.getAnnotations()) {
String name = annotationNameOf(a); // e.g. @QueryParam value/name
if (!seen.add(a.annotationType().getName() + ":" + name)) {
throw new IllegalStateException("Duplicate " + a.annotationType() + " for parameter");
}
} Try / catch
try {
enricher.collectClientParamData(...);
} catch (RestClientDefinitionException e) {
if (e.getMessage().startsWith("Duplicate")) { /* deduplicate annotations */ }
throw e;
} Prevention
- One annotation instance per parameter per annotation type
- Check parent interfaces for inherited duplicates when overriding methods
- Search the interface for repeated @QueryParam/@HeaderParam names before build
- Enable IDE duplicate-annotation inspections
When it happens
Trigger: Two annotations of the same type (e.g. two @QueryParam) targeting the same parameter name across the client interface hierarchy, or one annotation processed twice for a parameter with identical 'name' values.
Common situations: Copy-paste duplicates in an interface; inheriting annotated methods from a parent interface where a child re-declares the same parameter annotation; IDE auto-completion inserting a second @QueryParam on one parameter.
Related errors
- Class ${className} used in ${annotationName} on ${declaringC
- ${annotationName} method ${declaringClass}#${staticMethodNam
- ${annotationName} method ${methodName} not found on ${declar
- ${annotationName} method ${declaringClass}#${methodName} has
- Duplicate ClientHeaderParam annotation for header: ${headerN
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/be3e24aba91eb8a8.
Report an issue: GitHub.