quarkusio/quarkus · error · DeploymentException

Class %s has no fields. Parameters containers are only suppo

Error message

Class %s has no fields. Parameters containers are only supported if they have at least one annotated field.

What it means

When a @BeanParam class has no field extractors and requires no injection, ServerEndpointIndexer checks its declared methods; if there are none, the class is completely empty, so deployment fails with this DeploymentException. Parameter containers must have at least one annotated field to be meaningful.

Source

Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java:309

                    return intMethod;
                }
            }
        }
        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;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add at least one field annotated with a REST parameter annotation (@QueryParam, @HeaderParam, @PathParam, etc.).
  2. Remove the @BeanParam parameter if no parameters are needed.
  3. If annotations sit on methods, move them onto fields (see the companion error) — an empty class can never be a valid container.

Example fix

// before
class UserParams {}

// after
class UserParams {
    @QueryParam("name")
    String name;
}
Defensive patterns

Strategy: validation

Validate before calling

if (UserParams.class.getDeclaredFields().length == 0
    && UserParams.class.getDeclaredMethods().length == 0) {
    throw new IllegalStateException("@BeanParam class must declare at least one annotated field");
}

Prevention

When it happens

Trigger: Using an empty POJO as a @BeanParam parameter, e.g. get(@BeanParam MyParams p) where MyParams has no fields and no methods.

Common situations: Placeholder/scaffolding bean param classes left empty; refactoring removed all fields but kept the @BeanParam usage; copying a resource signature without the params class contents.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7b2284768cb28123. Report an issue: GitHub.