{"record":{"id":"06d7da5a63212934","repo":"Netflix/Hystrix","slug":"unsupported-rx-type","errorCode":null,"errorMessage":"unsupported rx type: {}","messagePattern":"unsupported rx type: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/GenericObservableCommand.java","lineNumber":176,"sourceCode":"            return false;\n        }\n        for (Class<? extends Throwable> ignoreException : ignoreExceptions) {\n            if (ignoreException.isAssignableFrom(throwable.getClass())) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private Observable toObservable(Object obj) {\n        if (Observable.class.isAssignableFrom(obj.getClass())) {\n            return (Observable) obj;\n        } else if (Completable.class.isAssignableFrom(obj.getClass())) {\n            return ((Completable) obj).toObservable();\n        } else if (Single.class.isAssignableFrom(obj.getClass())) {\n            return ((Single) obj).toObservable();\n        } else {\n            throw new IllegalStateException(\"unsupported rx type: \" + obj.getClass());\n        }\n    }\n}\n","sourceCodeStart":158,"sourceCodeEnd":180,"githubUrl":"https://github.com/Netflix/Hystrix/blob/5ce3bc58c38e7ca60ef2fe0e516e390e294ad941/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/GenericObservableCommand.java#L158-L180","documentation":"GenericObservableCommand.toObservable accepts only rx.Observable, rx.Completable, or rx.Single (RxJava 1.x types) as the user action's return value; anything else throws IllegalStateException. It exists because observable commands may be declared with several rx return shapes, and the bridge must convert each to Observable — an unrecognized type cannot be converted.","triggerScenarios":"An @HystrixCommand method executed in observable mode whose action returns an RxJava 2 type (io.reactivex.Observable/Single/Flowable/Completable), a java.util.concurrent.CompletableFuture, a plain value via a custom setup, or reactor's Flux/Mono — none of which are rx.* classes.","commonSituations":"Migrating a service from RxJava1 to RxJava2 while hystrix-javanica (built against RxJava1) is still in place; mixing Reactor and Hystrix in Spring WebFlux-era code; returning CompletableFuture from an observe-mode command.","solutions":["Return rx.Observable/rx.Single/rx.Completable (RxJava 1.x) from methods executed in observable mode with hystrix-javanica.","Convert other async types at the boundary: e.g. wrap CompletableFuture with Observable.from(future), or Reactor mono -> Observable via mono.toFuture() bridging or adapter libraries.","If the codebase has moved to RxJava2/Reactor, prefer a Hystrix adaptation layer (e.g. HystrixObservableCommand subclass written manually) or migrate off Javanica for those methods."],"exampleFix":"// before (RxJava2 leaking into javanica)\n@HystrixCommand\npublic io.reactivex.Single<User> getUser(String id) { ... }\n\n// after\n@HystrixCommand\npublic rx.Single<User> getUser(String id) { ... }\n// or bridge: rx.Observable.fromFuture(completableFuture)","handlingStrategy":"validation","validationCode":"static void assertRxJava1ReturnTypes(Class<?> clazz) {\n    for (Method m : clazz.getMethods()) {\n        Class<?> rt = m.getReturnType();\n        if (rt.getName().startsWith(\"io.reactivex.\") || rt.getName().startsWith(\"reactor.\")) {\n            if (m.isAnnotationPresent(HystrixCommand.class))\n                throw new IllegalStateException(m + \" returns \" + rt + \" — hystrix-javanica only supports rx.* (RxJava1) types\");\n        }\n    }\n}","typeGuard":"static boolean isSupportedRxType(Class<?> t) {\n    return rx.Observable.class.isAssignableFrom(t)\n            || rx.Completable.class.isAssignableFrom(t)\n            || rx.Single.class.isAssignableFrom(t);\n}","tryCatchPattern":"try { commandObservable = toObservable(actionResult); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"unsupported rx type\")) log.error(\"action returned {} — convert to rx.Observable/Single/Completable (RxJava1)\", resultClass); throw e; }","preventionTips":["Standardize on RxJava 1 rx.* types for any method executed through hystrix-javanica observable mode.","Ban io.reactivex/reactor imports in Hystrix-annotated service classes via ArchUnit/checkstyle.","Bridge CompletableFuture/Reactor at the adapter layer with Observable.from(...) rather than leaking them into commands."],"tags":["hystrix","javanica","rxjava","rxjava2","observable","type-mismatch"],"backgroundTag":null,"analyzedSha":"5ce3bc58c38e7ca60ef2fe0e516e390e294ad941","analyzedAt":"2026-08-14T10:55:35.600Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}