bumptech/glide · error · IllegalArgumentException

RequestOptionsExtensions must be public, with private constr

Error message

RequestOptionsExtensions must be public, with private constructors and only static methods. Found parameters in the constructor of: {}

What it means

Even when a constructor in a @GlideExtension class is private, it must take no arguments — extension classes hold no state, so parameterized constructors are meaningless and are rejected. validateExtensionConstructor throws when executableElement.getParameters() is non-empty after the private-modifier check passes.

Source

Thrown at annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/GlideExtensionValidator.java:89

  private static String getEnclosingClassName(Element element) {
    return element.getEnclosingElement().toString();
  }

  private static String getName(Element element) {
    return element.toString();
  }

  private static void validateExtensionConstructor(Element element) {
    if (!element.getModifiers().contains(Modifier.PRIVATE)) {
      throw new IllegalArgumentException(
          "RequestOptionsExtensions must be public, with private constructors and only static"
              + " methods. Found a non-private constructor in: "
              + getEnclosingClassName(element));
    }
    ExecutableElement executableElement = (ExecutableElement) element;
    if (!executableElement.getParameters().isEmpty()) {
      throw new IllegalArgumentException(
          "RequestOptionsExtensions must be public, with private constructors and only static"
              + " methods. Found parameters in the constructor of: "
              + getEnclosingClassName(element));
    }
  }

  private void validateGlideOption(ExecutableElement executableElement) {
    validateGlideOptionAnnotations(executableElement);
    validateGlideOptionParameters(executableElement);
    TypeMirror returnType = executableElement.getReturnType();
    if (!isBaseRequestOptions(returnType)) {
      throw new IllegalArgumentException(
          "@GlideOption methods should return a"
              + " BaseRequestOptions<?> object, but "
              + getQualifiedMethodName(executableElement)
              + " returns "
              + returnType
              + ". If you're using old style @GlideOption methods, your"

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Make the private constructor take no parameters: `private MyGlideExtension()`.
  2. Move any state or dependencies into the static @GlideOption/@GlideType method bodies (they receive the RequestOptions/RequestBuilder they operate on).

Example fix

// before
@GlideExtension
public class MyGlideExtension {
  private final Context context;
  private MyGlideExtension(Context context) { this.context = context; }
}

// after
@GlideExtension
public class MyGlideExtension {
  private MyGlideExtension() {}
}
Defensive patterns

Strategy: validation

Validate before calling

@Test void glideExtensionConstructorsHaveNoArgs() {
  for (java.lang.reflect.Constructor<?> c : MyGlideExtension.class.getDeclaredConstructors()) {
    assertEquals("@GlideExtension constructor must take no args: " + c, 0, c.getParameterCount());
  }
}

Prevention

When it happens

Trigger: GlideExtensionValidator.validateExtensionConstructor: after confirming the constructor is private, it checks `!executableElement.getParameters().isEmpty()` and throws. Hit by e.g. `private MyGlideExtension(Context context)` or any private constructor with one or more parameters.

Common situations: Refactoring an existing class into a @GlideExtension while leaving a parameterized private constructor; passing config/Context into the constructor instead of into the static @GlideOption/@GlideType methods.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/cf6070103dbf22a2. Report an issue: GitHub.