{"record":{"id":"b0356bed979756e0","repo":"OpenFeign/feign","slug":"method-return-type-is-not-completeablefuture-me","errorCode":null,"errorMessage":"Method return type is not CompleteableFuture: ${method}","messagePattern":"Method return type is not CompleteableFuture: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/feign/ReflectiveFeign.java","lineNumber":246,"sourceCode":"    }\n  }\n\n  private static class TargetSpecificationVerifier {\n    public static <T> void verify(Target<T> target) {\n      Class<T> type = target.type();\n      if (!type.isInterface()) {\n        throw new IllegalArgumentException(\"Type must be an interface: \" + type);\n      }\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    }","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/core/src/main/java/feign/ReflectiveFeign.java#L228-L264","documentation":"Validation in TargetSpecificationVerifier.verify for async targets: a method's return type is a subtype/specialization of CompletableFuture (e.g. CompletionStage or a custom subclass) rather than exactly CompletableFuture. The synchronous case is skipped, but Feign requires async methods to return exactly CompletableFuture so it can complete them; other async types cannot be fulfilled by the client.","triggerScenarios":"Thrown at core/src/main/java/feign/ReflectiveFeign.java:246 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Change the method's return type to CompletableFuture<T> exactly","Use CompletionStage only outside the Feign interface and convert from CompletableFuture in wrapper code","Remove the method from the async interface if it should be synchronous","Check generic wrappers/builders that may have rewritten the declared return type"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}