{"record":{"id":"2ed7b53a5a2d203a","repo":"OpenFeign/feign","slug":"status-code-statuscode-has-already-been-decla","errorCode":null,"errorMessage":"Status Code [${statusCode}] has already been declared to throw [${existing}] and [${duplicate}] - dupe definition","messagePattern":"Status Code \\[(.+?)\\] has already been declared to throw \\[(.+?)\\] and \\[(.+?)\\] - dupe definition","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"annotation-error-decoder/src/main/java/feign/error/AnnotationErrorDecoder.java","lineNumber":168,"sourceCode":"        }\n      }\n      return annotation;\n    }\n\n    static ErrorHandlingDefinition readAnnotation(\n        ErrorHandling errorHandling, Decoder responseBodyDecoder) {\n      ExceptionGenerator defaultException =\n          new ExceptionGenerator.Builder()\n              .withResponseBodyDecoder(responseBodyDecoder)\n              .withExceptionType(errorHandling.defaultException())\n              .build();\n      Map<Integer, ExceptionGenerator> statusCodesDefinition =\n          new HashMap<Integer, ExceptionGenerator>();\n\n      for (ErrorCodes statusCodeDefinition : errorHandling.codeSpecific()) {\n        for (int statusCode : statusCodeDefinition.codes()) {\n          if (statusCodesDefinition.containsKey(statusCode)) {\n            throw new IllegalStateException(\n                \"Status Code [\"\n                    + statusCode\n                    + \"] \"\n                    + \"has already been declared to throw [\"\n                    + statusCodesDefinition.get(statusCode).getExceptionType().getName()\n                    + \"] \"\n                    + \"and [\"\n                    + statusCodeDefinition.generate()\n                    + \"] - dupe definition\");\n          }\n          statusCodesDefinition.put(\n              statusCode,\n              new ExceptionGenerator.Builder()\n                  .withResponseBodyDecoder(responseBodyDecoder)\n                  .withExceptionType(statusCodeDefinition.generate())\n                  .build());\n        }\n      }","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/annotation-error-decoder/src/main/java/feign/error/AnnotationErrorDecoder.java#L150-L186","documentation":"Thrown by AnnotationErrorDecoder.readAnnotation when the same HTTP status code is mapped to more than one exception class within a single @ErrorHandling configuration (duplicated across codeSpecific entries). The library requires each status code to map to exactly one exception so decoding is unambiguous. This fails fast at proxy creation time, not at request time.","triggerScenarios":"Declaring two @ErrorCodes entries in @ErrorHandling(codeSpecific={...}) whose codes() arrays contain the same integer; e.g. @ErrorCodes(codes={404}, generate=NotFoundA.class) and @ErrorCodes(codes={404}, generate=NotFoundB.class) on the same interface or method.","commonSituations":"Copy-pasting an @ErrorCodes block and forgetting to change the status code; merging two interfaces' error configs where both map 500; refactoring exception classes and leaving a stale duplicate entry.","solutions":["Remove or change the duplicate status code so each code appears in only one @ErrorCodes entry per @ErrorHandling annotation","Consolidate the entries so one exception covers the shared status code, or move one @ErrorCodes block to method-level @ErrorHandling to override the interface-level mapping","Search the annotated interface for all occurrences of the conflicting status code"],"exampleFix":"// before\n@ErrorHandling(codeSpecific = {\n    @ErrorCodes(codes = {404}, generate = UserNotFound.class),\n    @ErrorCodes(codes = {404}, generate = ResourceMissing.class)\n})\n// after\n@ErrorHandling(codeSpecific = {\n    @ErrorCodes(codes = {404}, generate = UserNotFound.class),\n    @ErrorCodes(codes = {410}, generate = ResourceMissing.class)\n})","handlingStrategy":"validation","validationCode":"Set<Integer> seen = new HashSet<>();\nfor (ErrorCodes ec : errorHandling.codeSpecific()) {\n  for (int code : ec.codes()) {\n    if (!seen.add(code)) {\n      throw new IllegalArgumentException(\"Duplicate status code mapped twice: \" + code);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try (Feign feign = Feign.builder()...build()) { ... } catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"has already been declared\")) { /* fix annotation config */ }\n}","preventionTips":["Keep each status code mapped exactly once per @ErrorHandling scope","Prefer method-level @ErrorHandling overrides instead of duplicating codes at interface level","Review @ErrorCodes blocks after merges and refactors for copy-pasted codes"],"tags":["java","feign","configuration","duplicate-status-code"],"backgroundTag":"conflicting-config-options","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"}