quarkusio/quarkus · error · IllegalStateException

@ClientExceptionMapper can only take parameters of type 'jak

Error message

@ClientExceptionMapper can only take parameters of type 'jakarta.ws.rs.core.Response' or 'java.lang.reflect.Method' Offending instance is '${className}#${methodName}'

What it means

While generating bytecode for an annotated client handler method, each parameter must be assignable from the available locals (the Response or the java.lang.reflect.Method). A parameter of any other type cannot be satisfied, so the build throws this IllegalStateException naming the offending method. (Note: despite the message prefix, this site lives in ClientRedirectHandler's generation code and reports @ClientExceptionMapper misuse.)

Source

Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/ClientRedirectHandler.java:124

        final int finalPriority = priority;
        gizmo.class_(generatedClassName, cc -> {
            cc.implements_(ResteasyReactiveResponseRedirectHandler.class);
            cc.defaultConstructor();
            cc.method("handle", mc -> {
                mc.returning(URI.class);
                ParamVar response = mc.parameter("response", Response.class);
                mc.body(bc -> {
                    LinkedHashMap<String, Expr> targetMethodParams = new LinkedHashMap<>();
                    for (Type paramType : target.parameterTypes()) {
                        Expr targetMethodParamHandle;
                        if (paramType.name().equals(ResteasyReactiveDotNames.RESPONSE)) {
                            targetMethodParamHandle = response;
                        } else {
                            String message = DotNames.CLIENT_EXCEPTION_MAPPER + " can only take parameters of type '"
                                    + ResteasyReactiveDotNames.RESPONSE + "' or '" + DotNames.METHOD + "'"
                                    + " Offending instance is '" + target.declaringClass().name().toString()
                                    + "#" + target.name() + "'";
                            throw new IllegalStateException(message);
                        }
                        targetMethodParams.put(paramType.name().toString(), targetMethodParamHandle);
                    }

                    Expr resultHandle = bc.invokeStatic(methodDescOf(target),
                            targetMethodParams.values().toArray(new Expr[0]));
                    bc.return_(resultHandle);
                });
            });

            if (finalPriority != Priorities.USER) {
                cc.method("getPriority", mc -> {
                    mc.returning(int.class);
                    mc.body(bc -> {
                        bc.return_(Const.of(finalPriority));
                    });
                });
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Limit parameters to jakarta.ws.rs.core.Response and/or java.lang.reflect.Method
  2. Derive extra values inside the method body from the Response
  3. Check the @ClientExceptionMapper Javadoc for supported parameter types

Example fix

// before
@ClientExceptionMapper
static RuntimeException map(Response r, MyConfig cfg) { ... }
// after
@ClientExceptionMapper
static RuntimeException map(Response r) {
    return new RuntimeException("HTTP " + r.getStatus());
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean handlerParamsSupported(Method m) {
    for (Class<?> p : m.getParameterTypes()) {
        if (p != jakarta.ws.rs.core.Response.class && p != java.lang.reflect.Method.class) return false;
    }
    return true;
}

Try / catch

try {
    handler.generateResponseExceptionMapper(classResult, instance);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("can only take parameters")) { /* remove unsupported param */ }
    throw e;
}

Prevention

When it happens

Trigger: Declaring a @ClientExceptionMapper (or redirect handler processed by this generator) static method with a parameter that is neither jakarta.ws.rs.core.Response nor java.lang.reflect.Method.

Common situations: Adding convenience parameters like URI, String, or custom DTOs; copying server-side mapper signatures; refactoring that introduced a new parameter without updating generation support.

Related errors


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