quarkusio/quarkus · error · DeploymentException
Method '%s' of class '%s' is annotated with @%s annotation w
Error message
Method '%s' of class '%s' is annotated with @%s annotation which is prohibited. Classes used as @BeanParam parameters must have a JAX-RS parameter annotation on fields only.
What it means
RESTEasy Reactive's ServerEndpointIndexer validates classes used as @BeanParam parameters during deployment. JAX-RS requires that @BeanParam classes carry JAX-RS parameter annotations (@QueryParam, @HeaderParam, etc.) on their FIELDS only; placing such an annotation on a method is prohibited, so the build step throws a DeploymentException and the application fails to start.
Source
Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java:670
return new PeriodParamConverter.Supplier();
}
throw new RuntimeException(
contextualizeErrorMessage("Unable to handle temporal type '" + paramType + "'", currentMethodInfo));
}
private void validateMethodsForInjectableBean(ClassInfo currentClassInfo) {
// do not check methods of records, they get the annotations from their record components, but that's automatic:
// they are actually placed on the constructor parameters and also end up on the fields and methods
if (currentClassInfo.isRecord()) {
return;
}
for (MethodInfo method : currentClassInfo.methods()) {
for (AnnotationInstance annotation : method.annotations()) {
if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {
for (DotName annotationForField : JAX_RS_ANNOTATIONS_FOR_FIELDS) {
if (annotation.name().equals(annotationForField)) {
throw new DeploymentException(String.format(
"Method '%s' of class '%s' is annotated with @%s annotation which is prohibited. "
+ "Classes used as @BeanParam parameters must have a JAX-RS parameter annotation on "
+ "fields only.",
method.name(), currentClassInfo.name().toString(),
annotation.name().withoutPackagePrefix()));
}
}
}
}
}
}
private String contextualizeErrorMessage(String errorMessage, MethodInfo currentMethodInfo) {
errorMessage += ". Offending method if '" + currentMethodInfo.name() + "' of class '"
+ currentMethodInfo.declaringClass().name() + "'";
return errorMessage;
}
View on GitHub (pinned to e1c734241f)
Solutions
- Move the JAX-RS parameter annotation from the method to the corresponding field in the @BeanParam class
- If annotated setters are used, annotate the field directly and leave the setter unannotated
- If the class is a record, annotations on components are handled automatically - consider converting to a record
- Remove any duplicate method-level JAX-RS parameter annotations
Example fix
// before
class MyParams {
private String name;
@QueryParam("name")
public void setName(String name) { this.name = name; }
}
// after
class MyParams {
@QueryParam("name")
private String name;
public void setName(String name) { this.name = name; }
} Defensive patterns
Strategy: validation
Validate before calling
// Check all @BeanParam classes for JAX-RS annotations on methods
for (Class<?> beanParam : beanParamClasses) {
for (Method m : beanParam.getDeclaredMethods()) {
for (Annotation a : m.getAnnotations()) {
String n = a.annotationType().getName();
if (n.startsWith("jakarta.ws.rs.") && (n.contains("Param") || n.equals("jakarta.ws.rs.core.Context")))
throw new IllegalStateException(beanParam.getName() + " has " + n + " on method " + m.getName());
}
}
} Type guard
boolean isValidBeanParam(Class<?> c) {
return java.util.Arrays.stream(c.getDeclaredMethods())
.flatMap(m -> java.util.Arrays.stream(m.getAnnotations()))
.noneMatch(a -> a.annotationType().getName().matches("jakarta\\.ws\\.rs\\..*(Param|Context)"));
} Prevention
- Always place @QueryParam/@PathParam/@HeaderParam etc. on fields of @BeanParam classes
- Never rely on annotated setters for JAX-RS property injection
- Review @BeanParam classes after IDE auto-generation of getters/setters
- Prefer records for simple @BeanParam data carriers
When it happens
Trigger: A class used as a @BeanParam resource method parameter has a JAX-RS field annotation (e.g. @QueryParam, @PathParam, @HeaderParam, @CookieParam, @MatrixParam, @FormParam, @Context) placed on a setter or other method instead of (or in addition to) a field, and the class is not a record.
Common situations: Migrating legacy JAX-RS code that used annotated setters for property injection; code generated by IDEs that create getters/setters copying annotations; refactoring a @BeanParam class where annotations were accidentally moved from fields to methods.
Related errors
- Class %s has no fields. Parameters containers are only suppo
- No annotations found on fields at '%s'. Annotations like `@Q
- Body parameters (or non-annotated fields) are not allowed fo
- Failed to find converter for ${elementType}
- Failed to find converter for ${elementType}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/49352a7a537900f1.
Report an issue: GitHub.