OpenFeign/feign · error · IllegalArgumentException

ensure has a no-args constructor

Error message

ensure %s has a no-args constructor

What it means

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.

Solutions

  1. Add a no-argument constructor to the ContentHandlerWithResult implementation (it may be private or package-private)
  2. Make an inner handler class static, or move it to a top-level class, so its ctor takes no enclosing-instance argument
  3. Provide handler state via setters or fields initialized inside the handler instead of constructor parameters

Example fix

// before
class UserHandler implements ContentHandlerWithResult<User> {
  UserHandler(String extra) { ... } // no no-args ctor
}
// after
class UserHandler implements ContentHandlerWithResult<User> {
  public UserHandler() { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

static void requireNoArgCtor(Class<?> clazz) {
  try { clazz.getDeclaredConstructor(); }
  catch (NoSuchMethodException e) {
    throw new IllegalStateException(clazz + " needs a no-args constructor");
  }
}

Type guard

static boolean hasNoArgCtor(Class<?> c) {
  try { c.getDeclaredConstructor(); return true; }
  catch (NoSuchMethodException e) { return false; }
}

Try / catch

try {
  decoder = SAXDecoder.builder().contentHandlerWithResult(MyHandler.class).build();
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("no-args constructor")) {
    // fix the handler class definition
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/23fe37ffb8e55588. Report an issue: GitHub.

Appendix: source

Thrown at sax/src/main/java/feign/sax/SAXDecoder.java:166

      return this;
    }

    public SAXDecoder build() {
      return new SAXDecoder(handlerFactories);
    }

    private static class NewInstanceContentHandlerWithResultFactory<T>
        implements ContentHandlerWithResult.Factory<T> {

      private final Constructor<ContentHandlerWithResult<T>> ctor;

      private NewInstanceContentHandlerWithResultFactory(Class<ContentHandlerWithResult<T>> clazz) {
        try {
          this.ctor = clazz.getDeclaredConstructor();
          // allow private or package protected ctors
          ctor.setAccessible(true);
        } catch (NoSuchMethodException e) {
          throw new IllegalArgumentException("ensure " + clazz + " has a no-args constructor", e);
        }
      }

      @Override
      public ContentHandlerWithResult<T> create() {
        try {
          return ctor.newInstance();
        } catch (Exception e) {
          throw new IllegalArgumentException("exception attempting to instantiate " + ctor, e);
        }
      }
    }
  }

  @Override
  public boolean canDecode(Response response, Type type) {
    return Util.isXmlContentType(response);
  }

View on GitHub (pinned to e2a1e27560)