{"record":{"id":"8ec741dc89eafe26","repo":"quarkusio/quarkus","slug":"registering-a-contextresolver-via-a-lambda-is-not","errorCode":null,"errorMessage":"Registering a ContextResolver via a lambda is not supported","messagePattern":"Registering a ContextResolver via a lambda is not supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/ConfigurationImpl.java","lineNumber":326,"sourceCode":"                resourceWriters.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,\n                        resourceWriter);\n            }\n        }\n        if (component instanceof RxInvokerProvider) {\n            added = true;\n            Class<?> componentClass = component.getClass();\n            Type[] args = Types.findParameterizedTypes(componentClass, RxInvokerProvider.class);\n            rxInvokerProviders.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,\n                    (RxInvokerProvider<?>) component);\n        }\n        if (component instanceof ContextResolver) {\n            added = true;\n            Class<?> componentClass = component.getClass();\n            Type[] args = Types.findParameterizedTypes(componentClass, ContextResolver.class);\n            Class<?> key = args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class;\n            // in this case we are almost certain a lambda was used so we should fail\n            if ((key == Object.class) && component.getClass().isSynthetic()) {\n                throw new IllegalArgumentException(\"Registering a ContextResolver via a lambda is not supported\");\n            }\n            int effectivePriority = priority != null ? priority : determinePriority(component);\n            contextResolvers.computeIfAbsent(key, k -> new MultivaluedTreeMap<>())\n                    .add(effectivePriority, (ContextResolver<?>) component);\n        }\n        if (added) {\n            allInstances.put(component.getClass(), component);\n\n            Map<Class<?>, Integer> contracts = new HashMap<>();\n            for (Class<?> contractableClass : contractableClasses) {\n                contracts.put(contractableClass, priority);\n            }\n            this.contracts.put(component.getClass(), contracts);\n        }\n    }\n\n    public void register(Object component, Class<?>[] contracts) {\n        if (contracts == null || contracts.length == 0) {","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/jaxrs/ConfigurationImpl.java#L308-L344","documentation":"RESTEasy Reactive's client configuration stores ContextResolver instances keyed by the media type they handle, discovered via generic type introspection. Java lambdas are synthetic classes whose generic parameters cannot be reliably resolved, so the resolver would be keyed to Object.class and match everything incorrectly. The library detects this situation (key resolved to Object.class on a synthetic class) and refuses to register it rather than misbehaving at runtime.","triggerScenarios":"Calling clientBuilder.register((ContextResolver<Object>) type -> null) or similar register(...) invocation where the component is a lambda implementing ContextResolver, since Types.findParameterizedTypes cannot extract the media type argument from the synthetic lambda class.","commonSituations":"Registering context resolvers inline as lambdas when configuring a REST client or JAX-RS client; code that worked with an anonymous class fails after refactoring to a lambda; users unaware that generic type information is erased for lambdas.","solutions":["Replace the lambda with an explicit class that implements ContextResolver<YourMediaType>, stating the generic type in the class declaration.","Use an anonymous inner class instead of a lambda: new ContextResolver<JacksonConfig>() { ... } retains enough type information in some setups, but a named class is safest.","Register a named class instance: client.register(new MyContextResolver()).","If an explicit priority/type is needed, pass it via register(component, priority) — but the lambda itself still cannot be used for ContextResolver."],"exampleFix":"// before\nclient.register((ContextResolver<Object>) type -> myResolver.getContext(type));\n\n// after\npublic class MyContextResolver implements ContextResolver<ContextResolver<?>> {\n    @Override\n    public Object getContext(Class<?> type) { return myResolver.getContext(type); }\n}\nclient.register(new MyContextResolver());","handlingStrategy":"validation","validationCode":"if (component instanceof ContextResolver && component.getClass().isSynthetic()) {\n    throw new IllegalArgumentException(\"Use a named ContextResolver class, not a lambda\");\n}\nclient.register(component);","typeGuard":"boolean isRegisterableResolver(Object c) {\n    return !(c instanceof ContextResolver) || !c.getClass().isSynthetic();\n}","tryCatchPattern":"try {\n    client.register(resolver);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"ContextResolver via a lambda\")) {\n        client.register(new NamedContextResolver());\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always implement ContextResolver as a named class with an explicit generic type parameter.","Never use lambdas or method references for JAX-RS providers that rely on generic type introspection.","Add a code-review check for register(...) calls receiving lambdas."],"tags":["resteasy-reactive","jax-rs","context-resolver","lambda","client-registration"],"backgroundTag":"lambda-not-supported-for-generic-interface","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}