quarkusio/quarkus · error · UnsupportedOperationException
The `{instance.name}` annotation can only be used in methods
Error message
The `{instance.name}` annotation can only be used in methods or classes. What it means
Quarkus keys Jackson features (@JsonView, @CustomSerialization, @CustomDeserialization) by a target identifier computed from the annotation's target: class, method, or method parameter (request body). If the annotation is placed on any other target — most commonly a field — no identifier can be built and the deployment fails with this UnsupportedOperationException naming the annotation class.
Source
Thrown at extensions/resteasy-reactive/rest-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java:722
.asParameterizedType()
.arguments()
.stream()
.anyMatch(t -> fieldTypeHasSecureFields(t, indexView, typeToHasSecureField, needToDeleteCache));
}
return false;
}
private String getTargetId(AnnotationInstance instance) {
AnnotationTarget target = instance.target();
if (target.kind() == AnnotationTarget.Kind.CLASS) {
return getClassId(target.asClass());
} else if (target.kind() == AnnotationTarget.Kind.METHOD) {
return getMethodId(target.asMethod());
} else if (target.kind() == AnnotationTarget.Kind.METHOD_PARAMETER) {
return "request-body;" + getMethodId(target.asMethodParameter().method());
}
throw new UnsupportedOperationException(String.format("The `%s` annotation can only "
+ "be used in methods or classes.", instance.name()));
}
private String getClassId(ClassInfo classInfo) {
return classInfo.name().toString();
}
private String getMethodId(MethodInfo methodInfo) {
return getMethodId(methodInfo, methodInfo.declaringClass());
}
private String getMethodId(MethodInfo methodInfo, ClassInfo declaringClassInfo) {
List<String> parameterClassNames = new ArrayList<>(methodInfo.parametersCount());
for (Type parameter : methodInfo.parameterTypes()) {
parameterClassNames.add(parameter.name().toString());
}
return MethodId.get(methodInfo.name(), declaringClassInfo.name().toString(),
parameterClassNames.toArray(EMPTY_STRING_ARRAY));View on GitHub (pinned to e1c734241f)
Solutions
- Move the annotation from the field to the JAX-RS resource method (or resource class) that returns/consumes the DTO
- For per-field view filtering, keep @JsonView on DTO fields (plain Jackson handles that) and reference the view classes via @JsonView on the resource method only
- Ensure you import com.fasterxml.jackson.annotation.JsonView and apply it only on the resource endpoints for Quarkus REST features
- If you intended request-body customization, annotate the method parameter instead
Example fix
// before
class Resource {
@JsonView(Public.class) // wrong: on a field of the resource
private User user;
}
// after
class Resource {
@GET
@JsonView(Public.class)
public User get() { ... }
} Defensive patterns
Strategy: type-guard
Validate before calling
for (AnnotatedElement e : annotatedElements) {
if ((e instanceof Field) && e.isAnnotationPresent(JsonView.class))
throw new IllegalStateException("@JsonView on a field of a resource class is not supported; move it to the method");
} Type guard
static boolean isSupportedTarget(AnnotatedElement el) {
return el instanceof java.lang.reflect.Method || el instanceof Class<?> || isMethodParameter(el);
} Try / catch
try {
deploy();
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().contains("can only be used in methods or classes")) {
// relocate the annotation named in the message
}
} Prevention
- Only annotate JAX-RS resource classes/methods/parameters with @JsonView and custom (de)serialization annotations
- Keep field-level Jackson view annotations inside the DTO, driven from the resource method's @JsonView
- Check imports so the right @JsonView annotation is applied in the right place
- Review resource classes after migrating from plain Jackson/Spring
When it happens
Trigger: Putting @JsonView (or @CustomSerialization/@CustomDeserialization) on a field, enum constant, or other non class/method/parameter element of a JAX-RS resource class.
Common situations: Habit from plain Jackson where @JsonView is commonly used on fields/properties; migrating a Spring or standard-Jackson DTO annotation set onto Quarkus REST resources; accidental import of the wrong @JsonView annotation placed at field level in the resource class.
Related errors
- Unsupported target:
- Annotation ${dotName} was not expected on a target of kind $
- 'quarkus-narayana-lra' can only work if 'quarkus-rest-jackso
- Invalid annotation target for @TemplateContents: <target>
- Invalid annotation target for @TemplateGlobal: <annotation>
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0a873a6a88e85636.
Report an issue: GitHub.