{"record":{"id":"6aa1cc8ec72ac44f","repo":"OpenFeign/feign","slug":"method-return-type-is-not-parameterized-method","errorCode":null,"errorMessage":"Method return type is not parameterized: ${method}","messagePattern":"Method return type is not parameterized: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/feign/ReflectiveFeign.java","lineNumber":254,"sourceCode":"      }\n\n      for (final Method m : type.getMethods()) {\n        final Class<?> retType = m.getReturnType();\n\n        if (!CompletableFuture.class.isAssignableFrom(retType)) {\n          continue; // synchronous case\n        }\n\n        if (retType != CompletableFuture.class) {\n          throw new IllegalArgumentException(\n              \"Method return type is not CompleteableFuture: \"\n                  + getFullMethodName(type, retType, m));\n        }\n\n        final Type genRetType = m.getGenericReturnType();\n\n        if (!(genRetType instanceof ParameterizedType)) {\n          throw new IllegalArgumentException(\n              \"Method return type is not parameterized: \" + getFullMethodName(type, genRetType, m));\n        }\n\n        if (((ParameterizedType) genRetType).getActualTypeArguments()[0] instanceof WildcardType) {\n          throw new IllegalArgumentException(\n              \"Wildcards are not supported for return-type parameters: \"\n                  + getFullMethodName(type, genRetType, m));\n        }\n      }\n    }\n\n    private static String getFullMethodName(Class<?> type, Type retType, Method m) {\n      return retType.getTypeName() + \" \" + type.toGenericString() + \".\" + m.getName();\n    }\n  }\n}\n","sourceCodeStart":236,"sourceCodeEnd":271,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/core/src/main/java/feign/ReflectiveFeign.java#L236-L271","documentation":"Feign's ReflectiveFeign.verify() inspects interface methods whose return type must be a parameterized type (e.g. Response<T> for async/CompletableFuture-style methods) so it can extract the element type. This IllegalArgumentException is thrown when a method's generic return type is raw or non-parameterized, so Feign cannot determine the expected response type.","triggerScenarios":"Declaring an interface method whose generic return type is not parameterized (e.g. returning a raw type or a non-generic type where a parameterized type like CompletableFuture<Response> is required) and then building a client with Feign.builder().target(...) — the check runs in verify() during proxy creation.","commonSituations":"Copy-pasting method signatures without generics, erasing generics to silence compiler warnings, or using a return type like CompletableFuture without the element type in async configurations.","solutions":["Add the type parameter to the return type, e.g. CompletableFuture<Response<MyDto>> instead of raw CompletableFuture<Response>","Check the full method name in the error message and inspect that exact method in your interface","If the method should not use generic returns, align it with the contract (parameterized Request/Reply types)","Avoid wildcard type arguments; use concrete type parameters (see related wildcard error)"],"exampleFix":"// before\ninterface Api { CompletableFuture<Response> get(String id); }\n// after\ninterface Api { CompletableFuture<Response<MyDto>> get(String id); }","handlingStrategy":"validation","validationCode":"static void checkReturnType(java.lang.reflect.Method m) {\n  if (!(m.getGenericReturnType() instanceof java.lang.reflect.ParameterizedType)) {\n    throw new IllegalStateException(\"Return type must be parameterized: \" + m);\n  }\n}","typeGuard":"if (java.lang.reflect.Method m != null && m.getGenericReturnType() instanceof java.lang.reflect.ParameterizedType pt && !(pt.getActualTypeArguments()[0] instanceof java.lang.reflect.WildcardType)) { /* safe to use */ }","tryCatchPattern":"try {\n  MyApi api = Feign.builder().target(MyApi.class, url);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Method return type is not parameterized\")) {\n    throw new ConfigurationException(\"Fix interface return type: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Always declare concrete generic return types on Feign client interfaces","Enable IDE inspections for raw type usage","Add a startup-time reflection test that builds every Feign interface early","Never silence raw-types warnings with @SuppressWarnings"],"tags":["java","reflection","generics","feign-client"],"backgroundTag":"type-mismatch","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}