quarkusio/quarkus · error · IllegalArgumentException

Cannot merge dependencies with different module names

Error message

Cannot merge dependencies with different module names

What it means

DependencyInfo.merge combines two DependencyInfo records that represent the same module dependency observed from different sources. It refuses to merge when the two have different module names, because the result would be ill-defined. Callers are expected to group dependencies by module name before merging.

Source

Thrown at extensions/packaging/modular/spi/src/main/java/io/quarkus/modular/spi/model/DependencyInfo.java:24

import io.smallrye.common.constraint.Assert;
import io.smallrye.modules.desc.Dependency;
import io.smallrye.modules.desc.PackageAccess;

public record DependencyInfo(
        String moduleName,
        Dependency.Modifier.Set modifiers,
        Map<String, PackageAccess> packageAccesses) {
    public DependencyInfo {
        Assert.checkNotNullParam("moduleName", moduleName);
        Assert.checkNotNullParam("modifiers", modifiers);
        packageAccesses = Map.copyOf(Assert.checkNotNullParam("packageAccesses", packageAccesses));
    }

    public static DependencyInfo merge(DependencyInfo a, DependencyInfo b) {
        String moduleName = a.moduleName;
        if (!moduleName.equals(b.moduleName)) {
            throw new IllegalArgumentException("Cannot merge dependencies with different module names");
        }
        // merge modifiers but non-synthetic takes priority over synthetic
        Dependency.Modifier.Set modifiers = a.modifiers.xor(Dependency.Modifier.SYNTHETIC)
                .withAll(b.modifiers.xor(Dependency.Modifier.SYNTHETIC))
                .xor(Dependency.Modifier.SYNTHETIC);
        Map<String, PackageAccess> packageAccesses = Stream.concat(
                a.packageAccesses.entrySet().stream(),
                b.packageAccesses.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, PackageAccess::max));
        return new DependencyInfo(moduleName, modifiers, packageAccesses);
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Group DependencyInfo instances by moduleName before merging (Map<String, List<DependencyInfo>> keyed by getModuleName)
  2. Fix the aggregation code so a/b are guaranteed to refer to the same module
  3. If the modules genuinely differ, keep them separate instead of merging

Example fix

// before: blind pairwise merge
DependencyInfo m = DependencyInfo.merge(a, b);
// after: guard by module name
DependencyInfo m = a.getModuleName().equals(b.getModuleName())
        ? DependencyInfo.merge(a, b) : a;
Defensive patterns

Strategy: validation

Validate before calling

if (a.getModuleName() == null || !a.getModuleName().equals(b.getModuleName())) {
    throw new IllegalArgumentException("Refusing to merge dependencies with different module names");
}
DependencyInfo merged = DependencyInfo.merge(a, b);

Type guard

boolean isMergeable(DependencyInfo a, DependencyInfo b) {
    return a != null && b != null
            && java.util.Objects.equals(a.getModuleName(), b.getModuleName());
}

Try / catch

try {
    return DependencyInfo.merge(a, b);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("different module names")) {
        throw new IllegalStateException("Merge called across modules: "
                + a.getModuleName() + " vs " + b.getModuleName(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling DependencyInfo.merge(a, b) where a.moduleName != b.moduleName — e.g. merging synthetic and non-synthetic entries for different modules, or a bug in aggregation code that pairs up wrong entries.

Common situations: Downstream tooling (custom build steps over the modular SPI) merging a dependency list without keying by module name; refactors that change module naming between build steps.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/b082c84fcbbbf694. Report an issue: GitHub.