{"record":{"id":"aa4d87214ec0ab7d","repo":"quarkusio/quarkus","slug":"expected-a-clientinvocationbuilder","errorCode":null,"errorMessage":"Expected a ClientInvocationBuilder","messagePattern":"Expected a ClientInvocationBuilder","errorType":"exception","errorClass":"ProcessingException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-classic/resteasy-mutiny-common/runtime/src/main/java/io/quarkus/resteasy/mutiny/common/runtime/MultiRxInvokerImpl.java","lineNumber":32,"sourceCode":"import jakarta.ws.rs.sse.SseEventSource;\n\nimport org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder;\nimport org.jboss.resteasy.plugins.providers.sse.InboundSseEventImpl;\nimport org.jboss.resteasy.plugins.providers.sse.client.SseEventSourceImpl;\n\nimport io.smallrye.mutiny.Multi;\nimport io.smallrye.mutiny.subscription.BackPressureStrategy;\n\npublic class MultiRxInvokerImpl implements MultiRxInvoker {\n\n    private static Object monitor = new Object();\n    private ClientInvocationBuilder syncInvoker;\n    private ScheduledExecutorService executorService;\n    private BackPressureStrategy backpressureStrategy = BackPressureStrategy.BUFFER;\n\n    public MultiRxInvokerImpl(final SyncInvoker syncInvoker, final ExecutorService executorService) {\n        if (!(syncInvoker instanceof ClientInvocationBuilder)) {\n            throw new ProcessingException(\"Expected a ClientInvocationBuilder\");\n        }\n        this.syncInvoker = (ClientInvocationBuilder) syncInvoker;\n        if (executorService instanceof ScheduledExecutorService) {\n            this.executorService = (ScheduledExecutorService) executorService;\n        }\n    }\n\n    @Override\n    public BackPressureStrategy getBackPressureStrategy() {\n        return backpressureStrategy;\n    }\n\n    @Override\n    public void setBackPressureStrategy(BackPressureStrategy strategy) {\n        this.backpressureStrategy = strategy;\n    }\n\n    @Override","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-classic/resteasy-mutiny-common/runtime/src/main/java/io/quarkus/resteasy/mutiny/common/runtime/MultiRxInvokerImpl.java#L14-L50","documentation":"MultiRxInvokerImpl is Quarkus' reactive invoker for RESTEasy Client and only works with RESTEasy's concrete ClientInvocationBuilder, which exposes the internals needed for streaming a Multi. The constructor type-checks the SyncInvoker argument and throws this ProcessingException if it is any other SyncInvoker implementation (e.g. a plain Jersey-style or wrapper invoker). It indicates the reactive client extension is being used with an incompatible client stack.","triggerScenarios":"Constructing new MultiRxInvokerImpl(syncInvoker, executorService) — directly or via client.rx(MultiRxInvokerImpl.class) — when syncInvoker is not an instance of org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.","commonSituations":"Using the Quarkus RESTEasy Reactive client extensions (resteasy-mutiny) on the wrong client implementation on the classpath (e.g. standard JAX-RS client from another provider), or calling RxInvoker APIs through a wrapped/proxied invoker.","solutions":["Ensure you are using the RESTEasy Classic client from Quarkus (rest-client / resteasy-client-jaxrs), not another JAX-RS client implementation.","Call the invoker through the standard API: client.invocation(...).rx(MultiRxInvokerImpl.class) on a WebTarget built by ResteasyClient so the SyncInvoker is a ClientInvocationBuilder.","If you must construct it manually, pass builder from ResteasyClient.target(...).request() castable to ClientInvocationBuilder, or check instanceof before constructing."],"exampleFix":"// before\nMultiRxInvokerImpl invoker = new MultiRxInvokerImpl(someGenericSyncInvoker, exec); // ProcessingException\n\n// after\nResteasyClient client = (ResteasyClient) ClientBuilder.newClient();\nClientInvocationBuilder sync = (ClientInvocationBuilder) client.target(url).request();\nMultiRxInvokerImpl invoker = new MultiRxInvokerImpl(sync, exec);","handlingStrategy":"type-guard","validationCode":"if (!(syncInvoker instanceof ClientInvocationBuilder)) {\n    throw new IllegalStateException(\"MultiRxInvokerImpl requires a RESTEasy ClientInvocationBuilder; got \" + syncInvoker.getClass());\n}","typeGuard":"static boolean supportsMulti(SyncInvoker invoker) {\n    return invoker instanceof org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder;\n}","tryCatchPattern":"try {\n    MultiRxInvokerImpl invoker = new MultiRxInvokerImpl(syncInvoker, exec);\n} catch (ProcessingException e) {\n    if (e.getMessage().contains(\"Expected a ClientInvocationBuilder\")) {\n        throw new IllegalStateException(\"Use the RESTEasy Classic client so rx() receives a ClientInvocationBuilder\", e);\n    }\n    throw e;\n}","preventionTips":["Use Quarkus' RESTEasy Classic client, not another JAX-RS Client implementation","Obtain invokers via WebTarget.request().rx(...) so the concrete builder type is preserved","Avoid wrapping/proxying the SyncInvoker before passing it to the Multi invoker"],"tags":["resteasy","client","reactive","mutiny","type-mismatch"],"backgroundTag":"incompatible-client-invoker-type","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"}