quarkusio/quarkus · error · IllegalArgumentException
When '@ServerExceptionMapper' is used without a value, then
Error message
When '@ServerExceptionMapper' is used without a value, then the annotated method must contain a method parameter that extends 'Throwable'. Offending method is '${targetMethod.name()}' of class '${targetMethod.declaringClass().name().toString()}' What it means
When @ServerExceptionMapper is used without a value, RESTEasy Reactive must infer the handled exception from a Throwable-typed method parameter. If no parameter extends Throwable, the handled exception type cannot be determined and an IllegalArgumentException is thrown at build time.
Source
Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/exceptionmappers/ServerExceptionMapperGenerator.java:370
// handle the case where we deduce the type of exception handler by the Throwable defined in method parameters
Type deducedHandledExceptionType = null;
List<Type> methodParameters = targetMethod.parameterTypes();
for (Type methodParameter : methodParameters) {
if (methodParameter.kind() == Type.Kind.CLASS) {
Class<?> methodParameterClass = getClassByName(methodParameter.name().toString());
if (methodParameterClass != null && Throwable.class.isAssignableFrom(methodParameterClass)) {
if (deducedHandledExceptionType != null) {
throw new IllegalArgumentException(
"Multiple method parameters found that extend 'Throwable'. When using '@ServerExceptionMapper', only one parameter can be of type 'Throwable'. Offending method is '"
+ targetMethod.name() + "' of class '"
+ targetMethod.declaringClass().name().toString() + "'");
}
deducedHandledExceptionType = methodParameter;
}
}
}
if (deducedHandledExceptionType == null) {
throw new IllegalArgumentException(
"When '@ServerExceptionMapper' is used without a value, then the annotated method must contain a method parameter that extends 'Throwable'. Offending method is '"
+ targetMethod.name() + "' of class '" + targetMethod.declaringClass().name().toString() + "'");
}
return new Type[] { deducedHandledExceptionType };
}
private static Set<String> getCommonHierarchyOfExceptions(Type[] handledExceptions) {
Set<String> commonHierarchy = new HashSet<>();
boolean first = true;
for (Type handledException : handledExceptions) {
Class<?> handledExceptionClass = getClassByName(handledException.name().toString());
while (handledExceptionClass != null && !handledExceptionClass.equals(Throwable.class)) {
String handledExceptionClassName = handledExceptionClass.getName();
if (first) {
commonHierarchy.add(handledExceptionClassName);
} else if (!commonHierarchy.contains(handledExceptionClassName)) {
commonHierarchy.remove(handledExceptionClassName);
}View on GitHub (pinned to e1c734241f)
Solutions
- Add a parameter that extends Throwable (the exception you want to map)
- Or specify the handled type explicitly: @ServerExceptionMapper(NotFoundException.class) and keep a Throwable-compatible signature
- Check that the method signature wasn't accidentally changed during refactoring
Example fix
// before
@ServerExceptionMapper
public Response map(UriInfo uriInfo) {...}
// after
@ServerExceptionMapper
public Response map(NotFoundException e, UriInfo uriInfo) {...} Defensive patterns
Strategy: validation
Validate before calling
// Ensure value-less @ServerExceptionMapper methods declare a Throwable param
for (Method m : mapperMethods) {
boolean hasThrowable = java.util.Arrays.stream(m.getParameterTypes())
.anyMatch(Throwable.class::isAssignableFrom);
if (!hasThrowable) throw new IllegalStateException(m + " needs a Throwable parameter");
} Type guard
boolean declaresThrowableParam(Method m) {
return java.util.Arrays.stream(m.getParameterTypes())
.anyMatch(Throwable.class::isAssignableFrom);
} Prevention
- Always list the mapped exception as the first mapper parameter
- Use @ServerExceptionMapper(SpecificException.class) only together with a Throwable-compatible signature
- Run an ArchUnit/unit check over mapper methods in CI
- Re-check signatures after refactors that touch handler parameters
When it happens
Trigger: @ServerExceptionMapper (no value) applied to a method whose parameters are all non-Throwable types (e.g. only UriInfo, HttpHeaders, or nothing).
Common situations: Forgetting to declare the exception parameter; adding @ServerExceptionMapper to a helper method that takes only request context objects; renaming/refactoring away the exception parameter.
Related errors
- ReturnType: '${returnType}' is not supported
- Multiple method parameters found that extend 'Throwable'. Wh
- Parameter '${parameterName}' of method '${targetMethod.name(
- Parameter '${parameterName}' of method '${targetMethod.name(
- The combination of '@${annotationName}' and '@ServerRequestF
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/58d0fef5564d9c28.
Report an issue: GitHub.