{"record":{"id":"23fe37ffb8e55588","repo":"OpenFeign/feign","slug":"ensure-s-has-a-no-args-constructor","errorCode":null,"errorMessage":"ensure %s has a no-args constructor","messagePattern":"ensure (.+?) has a no-args constructor","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sax/src/main/java/feign/sax/SAXDecoder.java","lineNumber":166,"sourceCode":"      return this;\n    }\n\n    public SAXDecoder build() {\n      return new SAXDecoder(handlerFactories);\n    }\n\n    private static class NewInstanceContentHandlerWithResultFactory<T>\n        implements ContentHandlerWithResult.Factory<T> {\n\n      private final Constructor<ContentHandlerWithResult<T>> ctor;\n\n      private NewInstanceContentHandlerWithResultFactory(Class<ContentHandlerWithResult<T>> clazz) {\n        try {\n          this.ctor = clazz.getDeclaredConstructor();\n          // allow private or package protected ctors\n          ctor.setAccessible(true);\n        } catch (NoSuchMethodException e) {\n          throw new IllegalArgumentException(\"ensure \" + clazz + \" has a no-args constructor\", e);\n        }\n      }\n\n      @Override\n      public ContentHandlerWithResult<T> create() {\n        try {\n          return ctor.newInstance();\n        } catch (Exception e) {\n          throw new IllegalArgumentException(\"exception attempting to instantiate \" + ctor, e);\n        }\n      }\n    }\n  }\n\n  @Override\n  public boolean canDecode(Response response, Type type) {\n    return Util.isXmlContentType(response);\n  }","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/sax/src/main/java/feign/sax/SAXDecoder.java#L148-L184","documentation":"SAXDecoder instantiates the user-supplied ContentHandlerWithResult implementation reflectively via a no-args constructor (setAccessible is used to allow private ctors). If the class declares no accessible no-argument constructor, NoSuchMethodException is caught and rethrown as an IllegalArgumentException telling you to add one.","triggerScenarios":"Passing a ContentHandlerWithResult class to SAXDecoder.builder() (or via decoder configuration) whose class has only constructors with arguments, or is a non-static inner class whose implicit ctor requires the enclosing instance.","commonSituations":"Handlers written as inner classes (non-static) capturing outer state; handlers with constructor-injected dependencies; refactorings that added constructor parameters to previously no-arg handlers.","solutions":["Add a no-argument constructor to the ContentHandlerWithResult implementation (it may be private or package-private)","Make an inner handler class static, or move it to a top-level class, so its ctor takes no enclosing-instance argument","Provide handler state via setters or fields initialized inside the handler instead of constructor parameters"],"exampleFix":"// before\nclass UserHandler implements ContentHandlerWithResult<User> {\n  UserHandler(String extra) { ... } // no no-args ctor\n}\n// after\nclass UserHandler implements ContentHandlerWithResult<User> {\n  public UserHandler() { ... }\n}\n","handlingStrategy":"validation","validationCode":"static void requireNoArgCtor(Class<?> clazz) {\n  try { clazz.getDeclaredConstructor(); }\n  catch (NoSuchMethodException e) {\n    throw new IllegalStateException(clazz + \" needs a no-args constructor\");\n  }\n}","typeGuard":"static boolean hasNoArgCtor(Class<?> c) {\n  try { c.getDeclaredConstructor(); return true; }\n  catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n  decoder = SAXDecoder.builder().contentHandlerWithResult(MyHandler.class).build();\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"no-args constructor\")) {\n    // fix the handler class definition\n  }\n  throw e;\n}","preventionTips":["Always give SAX content handlers an explicit no-args constructor","Make handler classes static or top-level, never non-static inner classes","Inject state via fields/setters rather than constructor parameters"],"tags":["sax","reflection","decoder","constructor"],"backgroundTag":"missing-required-argument","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"}