bumptech/glide · error · IllegalStateException

You cannot have more than one AppGlideModule, found: {}

Error message

You cannot have more than one AppGlideModule, found: {}

What it means

Glide permits at most one AppGlideModule per application because the generated entry point (GlideApp) and the merged module are singletons keyed off it. AppModuleProcessor.processModules collects every @GlideModule-annotated class that is an AppGlideModule and throws when the set size exceeds one. The full list of offending classes is printed so you can locate the duplicates.

Source

Thrown at annotation/compiler/src/main/java/com/bumptech/glide/annotation/compiler/AppModuleProcessor.java:58

    requestOptionsGenerator = new RequestOptionsGenerator(processingEnv, processorUtil);
    requestManagerGenerator = new RequestManagerGenerator(processingEnv, processorUtil);
    requestManagerFactoryGenerator =
        new RequestManagerFactoryGenerator(processingEnv, processorUtil);
    glideGenerator = new GlideGenerator(processingEnv, processorUtil);
    requestBuilderGenerator = new RequestBuilderGenerator(processingEnv, processorUtil);
  }

  void processModules(Set<? extends TypeElement> set, RoundEnvironment env) {
    for (TypeElement element : processorUtil.getElementsFor(GlideModule.class, env)) {
      if (processorUtil.isAppGlideModule(element)) {
        appGlideModules.add(element);
      }
    }

    processorUtil.debugLog("got app modules: " + appGlideModules);

    if (appGlideModules.size() > 1) {
      throw new IllegalStateException(
          "You cannot have more than one AppGlideModule, found: " + appGlideModules);
    }
  }

  boolean maybeWriteAppModule() {
    // appGlideModules is added to in order to catch errors where multiple AppGlideModules may be
    // present for a single application or library. Because we only add to appGlideModules, we use
    // isGeneratedAppGlideModuleWritten to make sure the GeneratedAppGlideModule is written at
    // most once.
    if (appGlideModules.isEmpty()) {
      return false;
    }
    TypeElement appModule = appGlideModules.get(0);
    processorUtil.debugLog("Processing app module: " + appModule);
    // If this package is null, it means there are no classes with this package name. One way this
    // could happen is if we process an annotation and reach this point without writing something
    // to the package. We do not error check here because that shouldn't happen with the
    // current implementation.

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Search the whole module graph (app + all AAR deps) for classes extending AppGlideModule annotated with @GlideModule and keep exactly one.
  2. If a duplicate comes from a library/AAR, file a bug against that library — only the application module should declare an AppGlideModule.
  3. If it comes from a product-flavor or buildVariant split, move the AppGlideModule into a source set shared by all variants or guard duplicates with flavor-specific sourceSet exclusions.
  4. Remove any stale hand-written com.bumptech.glide.AppGlideModule subclass left from a manifest-based migration.

Example fix

// before — two classes in the compilation
@GlideModule public class AppGlideModuleA extends AppGlideModule { ... }
@GlideModule public class AppGlideModuleB extends AppGlideModule { ... }

// after — keep a single AppGlideModule
@GlideModule public class AppGlideModuleA extends AppGlideModule { ... }
// delete AppGlideModuleB
Defensive patterns

Strategy: validation

Validate before calling

// In a build-time check (e.g. a gradle task or test), scan the classpath for AppGlideModules:
@Test void atMostOneAppGlideModule() throws Exception {
  long count = java.util.stream.Stream.of(new java.io.File("build/intermediates/javac/debug/classes").listFiles())
      .filter(f -> f.getName().endsWith(".class")).count(); // illustrative
  // Better: enforce in code review that exactly one @GlideModule extends AppGlideModule exists.
}

Prevention

When it happens

Trigger: AppModuleProcessor.processModules iterates processorUtil.getElementsFor(GlideModule.class, env), adds each isAppGlideModule(element) to appGlideModules, and throws when appGlideModules.size() > 1. Hit when the compilation contains two @GlideModule classes extending AppGlideModule, including one pulled in transitively from an AAR's generated sources or from a copied sample.

Common situations: Copying Glide's sample MyAppGlideModule into your app while a library module already declares one; merging modules from two products/flavors without excluding one; an old manifest-based AppGlideModule lingering alongside a new annotated one; an AAR you depend on shipping an AppGlideModule (which is itself a packaging bug in that AAR).

Related errors


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