quarkusio/quarkus · error · DeploymentException
No annotations found on fields at '%s'. Annotations like `@Q
Error message
No annotations found on fields at '%s'. Annotations like `@QueryParam` should be used in fields, not in methods.
What it means
RESTEasy Reactive extracts request parameter values from annotated FIELDS of @BeanParam containers. If no field is annotated but the class has methods, it concludes the annotations (@QueryParam, @HeaderParam, etc.) were placed on methods and throws this DeploymentException.
Source
Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java:313
return null;
}
@Override
protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i,
Set<String> fileFormNames) {
ClassInfo beanParamClassInfo = index.getClassByName(paramType.name());
InjectableBean injectableBean = scanInjectableBean(beanParamClassInfo,
actualEndpointInfo,
existingConverters, additionalReaders, injectableBeans, hasRuntimeConverters);
if ((injectableBean.getFieldExtractorsCount() == 0) && !injectableBean.isInjectionRequired()) {
long declaredMethodsCount = beanParamClassInfo.methods().stream()
.filter(m -> !m.name().equals("<init>") && !m.name().equals("<clinit>")).count();
if (declaredMethodsCount == 0) {
throw new DeploymentException(String.format(
"Class %s has no fields. Parameters containers are only supported if they have at least one annotated field.",
beanParamClassInfo.name()));
} else {
throw new DeploymentException(String.format("No annotations found on fields at '%s'. "
+ "Annotations like `@QueryParam` should be used in fields, not in methods.",
beanParamClassInfo.name()));
}
}
fileFormNames.addAll(injectableBean.getFileFormNames());
return injectableBean.isFormParamRequired();
}
@Override
protected boolean doesMethodHaveBlockingSignature(MethodInfo info) {
for (var i : methodScanners) {
if (i.isMethodSignatureAsync(info)) {
return false;
}
}
return true;
}View on GitHub (pinned to e1c734241f)
Solutions
- Move the REST parameter annotations from methods onto the corresponding fields.
- Use a record with annotated components for a compact immutable container.
- Delete the method annotations if they were added by mistake.
Example fix
// before
class Filters {
@QueryParam("sort")
public void setSort(String sort) { this.sort = sort; }
}
// after
class Filters {
@QueryParam("sort")
public String sort;
} Defensive patterns
Strategy: validation
Validate before calling
boolean anyAnnotatedField = false;
for (java.lang.reflect.Field f : Filters.class.getDeclaredFields()) {
if (f.isAnnotationPresent(jakarta.ws.rs.QueryParam.class)) { anyAnnotatedField = true; break; }
}
if (!anyAnnotatedField) throw new IllegalStateException("@QueryParam must be on fields, not methods"); Prevention
- Always annotate fields directly in @BeanParam classes.
- Check annotation placement in code reviews.
- Prefer records with annotated components for immutable containers.
When it happens
Trigger: Declaring class MyParams { @QueryParam("q") void setQ(String q) {...} } or putting @QueryParam on a getter, then using MyParams as a @BeanParam.
Common situations: Migrating from frameworks that bind via annotated setters; IDE-generated getters/setters receiving the annotations; assuming Spring-MVC-style property binding works here.
Related errors
- Class %s has no fields. Parameters containers are only suppo
- Body parameters (or non-annotated fields) are not allowed fo
- Could not create converter for ${elementType} for ${builder.
- @UnwrapException is only supported on classes. Offending tar
- Using @UnwrapException without a value is only supported on
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e6f3df051d421083.
Report an issue: GitHub.