{"record":{"id":"13611b65a6eeaf02","repo":"lysine-dev/retrofit","slug":"name-return-type-must-be-parameterized-as-nam","errorCode":null,"errorMessage":"${name} return type must be parameterized as ${name}<Foo> or ${name}<? extends Foo>","messagePattern":"(.+?) return type must be parameterized as (.+?)<Foo> or (.+?)<\\? extends Foo>","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/RxJavaCallAdapterFactory.java","lineNumber":114,"sourceCode":"  public @Nullable CallAdapter<?, ?> get(\n      Type returnType, Annotation[] annotations, Retrofit retrofit) {\n    Class<?> rawType = getRawType(returnType);\n    boolean isSingle = rawType == Single.class;\n    boolean isCompletable = rawType == Completable.class;\n    if (rawType != Observable.class && !isSingle && !isCompletable) {\n      return null;\n    }\n\n    if (isCompletable) {\n      return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);\n    }\n\n    boolean isResult = false;\n    boolean isBody = false;\n    Type responseType;\n    if (!(returnType instanceof ParameterizedType)) {\n      String name = isSingle ? \"Single\" : \"Observable\";\n      throw new IllegalStateException(\n          name\n              + \" return type must be parameterized\"\n              + \" as \"\n              + name\n              + \"<Foo> or \"\n              + name\n              + \"<? extends Foo>\");\n    }\n\n    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);\n    Class<?> rawObservableType = getRawType(observableType);\n    if (rawObservableType == Response.class) {\n      if (!(observableType instanceof ParameterizedType)) {\n        throw new IllegalStateException(\n            \"Response must be parameterized\" + \" as Response<Foo> or Response<? extends Foo>\");\n      }\n      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);\n    } else if (rawObservableType == Result.class) {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/lysine-dev/retrofit/blob/d0b112dad073b7fe49c953ebc46ff1b424cb1e51/retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/RxJavaCallAdapterFactory.java#L96-L132","documentation":"Retrofit's RxJava 1.x adapter supports Observable, Single, and Completable return types. Observable and Single must carry a generic element type; a raw type leaves the adapter unable to resolve the emitted item type, so RxJavaCallAdapterFactory throws IllegalStateException, interpolating the actual raw class name ('Single' or 'Observable') into the message. Completable is exempt because it has no type parameter.","triggerScenarios":"A method with a raw return type such as `Observable getUsers()` or `Single findUser()`. Thrown in get() when `returnType` is not a ParameterizedType and the type is not Completable; the `name` variable is set to 'Single' when isSingle else 'Observable'.","commonSituations":"Migrating from `Call<T>` to RxJava and omitting the generic; mixing RxJava 1 and 2 adapter types; suppress raw-types warnings.","solutions":["Parameterize the return type: `Observable<List<User>> getUsers();` or `Single<User> findUser(@Path(\"id\") long id);`","For fire-and-forget calls with no payload use Completable: `Completable deleteUser(@Path(\"id\") long id);`","For full response or error packaging use `Observable<Response<User>>` or `Observable<Result<User>>`."],"exampleFix":"// before\nObservable getUsers();\n// after\nObservable<List<User>> getUsers();","handlingStrategy":"validation","validationCode":"import java.lang.reflect.*;\nimport rx.*;\nstatic void assertRxTypesParameterized(Class<?> iface) {\n  for (Method m : iface.getDeclaredMethods()) {\n    Type rt = m.getGenericReturnType();\n    Class<?> raw = rt instanceof Class ? (Class<?>) rt : getRaw(rt);\n    if ((raw == Observable.class || raw == Single.class) && !(rt instanceof ParameterizedType)) {\n      throw new AssertionError(\"Raw \" + raw.getSimpleName() + \" return type on \" + m);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  MyService svc = retrofit.create(MyService.class);\n  Observable<List<User>> o = svc.getUsers();\n} catch (IllegalStateException e) {\n  throw new IllegalStateException(\"RxJava return type is raw on the service interface: \" + e.getMessage(), e);\n}","preventionTips":["Build with -Xlint:rawtypes so raw Observable/Single fail fast.","Prefer Completable for no-payload methods so no generic is needed.","Add a reflection unit test over the service interface."],"tags":["retrofit","rxjava","generics","java","type-system","observable"],"backgroundTag":null,"analyzedSha":"d0b112dad073b7fe49c953ebc46ff1b424cb1e51","analyzedAt":"2026-08-13T23:49:47.955Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}