{"record":{"id":"c6426725aa5ad422","repo":"OpenFeign/feign","slug":"too-many-constructors-marked-with-feignexceptionc","errorCode":null,"errorMessage":"Too many constructors marked with @FeignExceptionConstructor","messagePattern":"Too many constructors marked with @FeignExceptionConstructor","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"annotation-error-decoder/src/main/java/feign/error/ExceptionGenerator.java","lineNumber":223,"sourceCode":"\n    private Constructor<? extends Exception> getConstructor(\n        Class<? extends Exception> exceptionClass) {\n      Constructor<? extends Exception> preferredConstructor = null;\n      for (Constructor<?> constructor : exceptionClass.getConstructors()) {\n\n        FeignExceptionConstructor exceptionConstructor =\n            constructor.getAnnotation(FeignExceptionConstructor.class);\n        if (exceptionConstructor == null) {\n          continue;\n        }\n        Class<?>[] parameterTypes = constructor.getParameterTypes();\n        if (parameterTypes.length == 0) {\n          continue;\n        }\n        if (preferredConstructor == null) {\n          preferredConstructor = (Constructor<? extends Exception>) constructor;\n        } else {\n          throw new IllegalStateException(\n              \"Too many constructors marked with @FeignExceptionConstructor\");\n        }\n      }\n\n      if (preferredConstructor == null) {\n        try {\n          return exceptionClass.getConstructor();\n        } catch (NoSuchMethodException e) {\n          throw new IllegalStateException(\n              \"Cannot find any suitable constructor in class [\"\n                  + exceptionClass.getName()\n                  + \"] - did you forget to mark one with @FeignExceptionConstructor or at least\"\n                  + \" have a public default constructor?\",\n              e);\n        }\n      }\n      return preferredConstructor;\n    }","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/annotation-error-decoder/src/main/java/feign/error/ExceptionGenerator.java#L205-L241","documentation":"Thrown by ExceptionGenerator.getConstructor when more than one constructor of the exception class is annotated with @FeignExceptionConstructor. The annotation designates a single preferred constructor, so multiple annotated constructors make the choice ambiguous and the library refuses to guess.","triggerScenarios":"Annotating two or more constructors of the same exception class with @FeignExceptionConstructor, often after adding an overloaded constructor and annotating both.","commonSituations":"Adding a convenience constructor for tests and marking both with the annotation; merging branches where each added an annotated constructor.","solutions":["Keep @FeignExceptionConstructor on exactly one constructor and remove it from the others","If both constructors are needed, make one delegate to the annotated one via this(...) chaining instead of annotating both"],"exampleFix":"// before\npublic class ApiError extends RuntimeException {\n  @FeignExceptionConstructor\n  public ApiError(int status, String body) { ... }\n\n  @FeignExceptionConstructor\n  public ApiError(String body) { this(0, body); }\n}\n// after\npublic class ApiError extends RuntimeException {\n  @FeignExceptionConstructor\n  public ApiError(int status, String body) { ... }\n\n  public ApiError(String body) { this(0, body); }\n}","handlingStrategy":"validation","validationCode":"long marked = Arrays.stream(ApiError.class.getConstructors())\n    .filter(c -> c.isAnnotationPresent(FeignExceptionConstructor.class)).count();\nif (marked > 1) throw new IllegalStateException(\"Only one @FeignExceptionConstructor allowed\");","typeGuard":null,"tryCatchPattern":"try { Feign.builder().errorDecoder(decoder).build(); }\ncatch (IllegalStateException e) { if (e.getMessage().contains(\"Too many constructors\")) { ... } }","preventionTips":["Annotate exactly one constructor per exception class","Use constructor chaining (this(...)) for alternate signatures instead of extra annotations","Add an ArchUnit/reflection test asserting a single annotation per exception class"],"tags":["java","feign","reflection","ambiguous-constructor"],"backgroundTag":"invalid-argument-value","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"}