square/retrofit · error · IllegalStateException
Response must be parameterized as Response<Foo> or Response<
Error message
Response must be parameterized as Response<Foo> or Response<? extends Foo>
What it means
Thrown by RxJava2CallAdapterFactory when the outer reactive type is parameterized but its argument is raw `Response`. The factory needs `Response<T>` to extract T; raw Response fails the check at RxJava2CallAdapterFactory.java:131. Applies to Observable, Flowable, Single, and Maybe.
Source
Thrown at retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/RxJava2CallAdapterFactory.java:132
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name =
isFlowable ? "Flowable" : isSingle ? "Single" : isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(
name
+ " return type must be parameterized"
+ " as "
+ name
+ "<Foo> or "
+ name
+ "<? extends Foo>");
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(
"Response must be parameterized" + " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException(
"Result must be parameterized" + " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(
responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
}View on GitHub (pinned to d0b112dad0)
Solutions
- Parameterize Response: `Observable<Response<User>> getUser();`.
- Or drop the wrapper: `Observable<User> getUser();`.
- For unified body+error handling, use `Observable<Result<User>>`.
Example fix
// before
@GET("users/{id}")
Observable<Response> getUser(@Path("id") String id);
// after
@GET("users/{id}")
Observable<Response<User>> getUser(@Path("id") String id); Defensive patterns
Strategy: validation
Validate before calling
for (Method m : MyService.class.getDeclaredMethods()) {
Type rt = m.getGenericReturnType();
if (rt instanceof ParameterizedType
&& ((ParameterizedType) rt).getActualTypeArguments()[0] == retrofit2.Response.class) {
throw new IllegalStateException(m + " uses raw Response inside an RxJava2 type.");
}
} Try / catch
try {
retrofit.create(MyService.class).getUser("1");
} catch (IllegalStateException e) {
if (e.getMessage().contains("Response must be parameterized")) {
throw new IllegalStateException("Fix raw Response<> inside RxJava2 return in MyService.", e);
}
throw e;
} Prevention
- Always carry the body type into Response<>.
- Let the IDE flag raw inner types.
- Per-service smoke test in CI.
When it happens
Trigger: A service method returns `Observable<Response>` (or Flowable/Single/Maybe) with raw Response instead of `Observable<Response<User>>`.
Common situations: Switching a body return to a Response-wrapped return and dropping the inner generic; autocompleting Response without its argument.
Related errors
- Response must be parameterized as Response<Foo> or Response<
- Response must be parameterized as Response<Foo> or Response<
- Response must be parameterized as Response<Foo> or Response<
- ${name} return type must be parameterized as ${name}<Foo> or
- Result must be parameterized as Result<Foo> or Result<? exte
AI-assisted analysis of square/retrofit@d0b112dad0 (2026-08-04).
Data as JSON: /data/errors/1f624883a5935be1.json.
Report an issue: GitHub.