sbt-assembly "deduplicate" Merge Conflict in CI
sbt-assembly is building a fat JAR and found two dependencies that contribute the same file path with different contents. It refuses to pick one silently and asks for a merge strategy.
What this error means
sbt assembly fails with "deduplicate: different file contents found in the following", listing a path (often META-INF/..., module-info.class, or reference.conf) present in multiple jars.
[error] deduplicate: different file contents found in the following:
[error] .../netty-common-4.1.x.jar:META-INF/io.netty.versions.properties
[error] .../netty-handler-4.1.x.jar:META-INF/io.netty.versions.propertiesCommon causes
Two jars ship the same path
Multiple dependencies include the same resource (metadata, reference.conf, service files) with differing contents, so assembly cannot deduplicate automatically.
No merge strategy for the conflicting path
The default strategy errors on conflicts it does not know how to merge (e.g. module-info.class, duplicated META-INF entries).
How to fix it
Add a merge strategy for the path
Tell assembly how to handle the conflicting files - discard metadata, concat config, take first where safe.
// build.sbt
assembly / assemblyMergeStrategy := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case "module-info.class" => MergeStrategy.discard
case "reference.conf" => MergeStrategy.concat
case x =>
val old = (assembly / assemblyMergeStrategy).value
old(x)
}Remove the duplicate dependency
- Check whether two versions of the same library are both on the classpath.
- Exclude or align them so the duplicate path disappears.
- Prefer fixing the dependency graph over masking it with
discard.
How to prevent it
- Keep a merge strategy for common
META-INF/config conflicts. - Deduplicate library versions before reaching for
discard. - Use
concatfor additive config files, notdiscard.