{"record":{"id":"cf6070103dbf22a2","repo":"bumptech/glide","slug":"requestoptionsextensions-must-be-public-with-priv-cf6070","errorCode":null,"errorMessage":"RequestOptionsExtensions must be public, with private constructors and only static methods. Found parameters in the constructor of: {}","messagePattern":"RequestOptionsExtensions must be public, with private constructors and only static methods\\. Found parameters in the constructor of: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/GlideExtensionValidator.java","lineNumber":89,"sourceCode":"\n  private static String getEnclosingClassName(Element element) {\n    return element.getEnclosingElement().toString();\n  }\n\n  private static String getName(Element element) {\n    return element.toString();\n  }\n\n  private static void validateExtensionConstructor(Element element) {\n    if (!element.getModifiers().contains(Modifier.PRIVATE)) {\n      throw new IllegalArgumentException(\n          \"RequestOptionsExtensions must be public, with private constructors and only static\"\n              + \" methods. Found a non-private constructor in: \"\n              + getEnclosingClassName(element));\n    }\n    ExecutableElement executableElement = (ExecutableElement) element;\n    if (!executableElement.getParameters().isEmpty()) {\n      throw new IllegalArgumentException(\n          \"RequestOptionsExtensions must be public, with private constructors and only static\"\n              + \" methods. Found parameters in the constructor of: \"\n              + getEnclosingClassName(element));\n    }\n  }\n\n  private void validateGlideOption(ExecutableElement executableElement) {\n    validateGlideOptionAnnotations(executableElement);\n    validateGlideOptionParameters(executableElement);\n    TypeMirror returnType = executableElement.getReturnType();\n    if (!isBaseRequestOptions(returnType)) {\n      throw new IllegalArgumentException(\n          \"@GlideOption methods should return a\"\n              + \" BaseRequestOptions<?> object, but \"\n              + getQualifiedMethodName(executableElement)\n              + \" returns \"\n              + returnType\n              + \". If you're using old style @GlideOption methods, your\"","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/GlideExtensionValidator.java#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make the private constructor take no parameters: `private MyGlideExtension()`.","Move any state or dependencies into the static @GlideOption/@GlideType method bodies (they receive the RequestOptions/RequestBuilder they operate on)."],"exampleFix":"// before\n@GlideExtension\npublic class MyGlideExtension {\n  private final Context context;\n  private MyGlideExtension(Context context) { this.context = context; }\n}\n\n// after\n@GlideExtension\npublic class MyGlideExtension {\n  private MyGlideExtension() {}\n}","handlingStrategy":"validation","validationCode":"@Test void glideExtensionConstructorsHaveNoArgs() {\n  for (java.lang.reflect.Constructor<?> c : MyGlideExtension.class.getDeclaredConstructors()) {\n    assertEquals(\"@GlideExtension constructor must take no args: \" + c, 0, c.getParameterCount());\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep @GlideExtension constructors parameterless.","Push any per-call state into the static @GlideOption/@GlideType method parameters instead of the constructor."],"tags":["glide","annotation-processing","glideextension","constructor"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}