quarkusio/quarkus · error · IllegalStateException

Unable to resolve input and output types for handler class <

Error message

Unable to resolve input and output types for handler class <handlerClass.name()>

What it means

A concrete handleRequest method was found, but resolving its generic input/output types (walking the type hierarchy to bind type variables) failed — the resolved InputOutputTypes still contains unresolved type variables, so the handler cannot be registered with correct request/response classes.

Source

Thrown at extensions/amazon-lambda/deployment/src/main/java/io/quarkus/amazon/lambda/deployment/RequestHandlerJandexUtil.java:42

    private RequestHandlerJandexUtil() {
    }

    public static RequestHandlerJandexDefinition discoverHandlerMethod(String handlerClassName, IndexView index) {
        ClassInfo handlerClass = index.getClassByName(handlerClassName);
        if (handlerClass == null) {
            throw new IllegalArgumentException("RequestHandler class not found in the index: " + handlerClassName);
        }

        MethodInfo concreteHandleRequestMethod = findConcreteHandleRequestMethod(handlerClass, index);
        if (concreteHandleRequestMethod == null) {
            throw new IllegalStateException(
                    "Unable to find a concrete handleRequest method on handler class " + handlerClass.name());
        }

        Map<String, Type> typeMap = new HashMap<>();
        InputOutputTypes inputOutputTypes = resolveInputOutputTypes(handlerClass.name(), index, typeMap);
        if (isUnresolved(inputOutputTypes)) {
            throw new IllegalStateException(
                    "Unable to resolve input and output types for handler class " + handlerClass.name());
        }

        return new RequestHandlerJandexDefinition(handlerClass, concreteHandleRequestMethod, inputOutputTypes);
    }

    private static MethodInfo findConcreteHandleRequestMethod(ClassInfo handlerClass, IndexView index) {
        ClassInfo currentClass = handlerClass;

        // Look for implementations of the method in the class hierarchy
        while (currentClass != null && !OBJECT.equals(currentClass.name())) {
            for (MethodInfo method : currentClass.methods()) {
                if (isHandleRequestMethod(method) && !method.isSynthetic() && !method.isAbstract()) {
                    return method;
                }
            }

            Type superType = currentClass.superClassType();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Declare concrete generic types on your handler: implements RequestHandler<MyIn, MyOut>, not raw or open type variables
  2. Flatten the hierarchy — implement handleRequest directly on a concretely parameterized class
  3. If types come from a dependency, ensure that jar is Jandex-indexed so the type resolution can walk it
  4. Simplify wildcards/intersections (e.g. RequestHandler<List<?>, ?>) into named concrete types

Example fix

// before
class MyHandler implements RequestHandler<Map<String, ?>, List<?>> { ... }
// after
class MyHandler implements RequestHandler<Map<String, String>, List<String>> { ... }
Defensive patterns

Strategy: validation

Validate before calling

// bind generics concretely
typeCheck: class MyHandler implements RequestHandler<MyIn, MyOut> {} // never raw or type-variable parameters

Prevention

When it happens

Trigger: discoverHandlerMethod calls resolveInputOutputTypes(handlerClass.name(), index, typeMap); isUnresolved(inputOutputTypes) returns true after walking the class hierarchy for generic parameter bindings.

Common situations: Deep generic hierarchies where intermediate classes live in unindexed jars; exotic generics (wildcards, raw types) on handleRequest; handler declared as e.g. implements RequestHandler<T, T> with type variables never bound.

Related errors


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