apache/maven · warning

Duplicate enabled source detected: lang=%s, scope=%s, module

Error message

Duplicate enabled source detected: lang=%s, scope=%s, module=%s, directory=%s. First enabled source wins, this duplicate is ignored.

What it means

While materializing Maven 4 <source> declarations into SourceRoot entries, SourceHandlingContext.shouldAddSource() detected two enabled sources with identical identity: same language, same project scope, same module, and the same normalized directory path. The first declaration wins and the duplicate is dropped; a WARNING ModelProblem is also added to the problem collector, so the message reappears in the 'problems encountered while building the effective model' summary. Only enabled sources participate; disabled ones never collide. Introduced with the unified source handling in Maven 4.0.0.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/project/SourceHandlingContext.java:131

                    "Adding disabled source (will be filtered by getEnabledSourceRoots): lang={}, scope={}, module={}, dir={}",
                    sourceRoot.language(),
                    sourceRoot.scope(),
                    sourceRoot.module().orElse(null),
                    sourceRoot.directory());
            return true;
        }

        // Normalize path for consistent duplicate detection (handles symlinks, relative paths)
        Path normalizedDir = sourceRoot.directory().toAbsolutePath().normalize();
        SourceKey key = new SourceKey(
                sourceRoot.language(), sourceRoot.scope(), sourceRoot.module().orElse(null), normalizedDir);

        if (!declaredSources.add(key)) {
            String message = String.format(
                    "Duplicate enabled source detected: lang=%s, scope=%s, module=%s, directory=%s. "
                            + "First enabled source wins, this duplicate is ignored.",
                    key.language(), key.scope(), key.module() != null ? key.module() : "(none)", key.directory());
            LOGGER.warn(message);
            result.getProblemCollector()
                    .reportProblem(new DefaultModelProblem(
                            message,
                            Severity.WARNING,
                            Version.V41,
                            project.getModel().getDelegate(),
                            -1,
                            -1,
                            null));
            return false; // Don't add duplicate enabled source
        }

        LOGGER.debug(
                "Adding and tracking enabled source: lang={}, scope={}, module={}, dir={}",
                key.language(),
                key.scope(),
                key.module(),
                key.directory());

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Run mvn help:effective-pom and search for repeated <source> blocks with the same <directory> under the same build scope
  2. Delete one of the duplicate <source> declarations, keeping the intended one
  3. If both are conditionally needed, mark the less important one with <enabled>false</enabled> so it never competes
  4. Remove legacy build-helper / add-test-source mojos that add a directory Maven 4 already tracks via <source>

Example fix

<!-- before: same directory declared twice for lang=java, scope=main -->
<build>
  <sources>
    <source>
      <directory>src/main/java</directory>
      <language>java</language>
    </source>
    <source>
      <directory>src/main/java</directory>
      <language>java</language>
      <module>com.example.app</module>
    </source>
  </sources>
</build>

<!-- after: single declaration; extra roots get their own directory -->
<build>
  <sources>
    <source>
      <directory>src/main/java</directory>
      <language>java</language>
    </source>
    <source>
      <directory>src/generated/java</directory>
      <language>java</language>
    </source>
  </sources>
</build>
Defensive patterns

Strategy: validation

Validate before calling

# Lint POMs for duplicate source identities before building (bash)
python3 - <<'EOF'
import xml.etree.ElementTree as ET, sys
ns = {'m': 'http://maven.apache.org/POM/4.0.0'}
for pom in sys.argv[1:]:
    root = ET.parse(pom).getroot()
    seen = set()
    for s in root.iter('{http://maven.apache.org/POM/4.0.0}source'):
        if s.findtext('m:enabled', 'true', ns) in ('true', 'True'):
            key = (s.findtext('m:language', ns), s.findtext('m:directory', ns))
            if key in seen: sys.exit(f"duplicate enabled source {key} in {pom}")
            seen.add(key)
EOF

Prevention

When it happens

Trigger: A POM (or an effective model merged from profiles/parents) declares two <source> elements under <build> with the same language/scope/module and directory, both enabled (default). Typical: an explicit <source> duplicating the conventional src/main/java declared via a default profile plus one in the base build section.

Common situations: Upgrading a project to Maven 4 <source> declarations and keeping the legacy build-helper add-source or build-helper-maven-plugin addition of the same directory; a profile that adds a source root also present in the active base model; copy-pasted <source> blocks with identical directories.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/cae119f25d255bf8. Report an issue: GitHub.