{"record":{"id":"cae119f25d255bf8","repo":"apache/maven","slug":"duplicate-enabled-source-detected-lang-s-scope","errorCode":null,"errorMessage":"Duplicate enabled source detected: lang=%s, scope=%s, module=%s, directory=%s. First enabled source wins, this duplicate is ignored.","messagePattern":"Duplicate enabled source detected: lang=(.+?), scope=(.+?), module=(.+?), directory=(.+?)\\. First enabled source wins, this duplicate is ignored\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"impl/maven-core/src/main/java/org/apache/maven/project/SourceHandlingContext.java","lineNumber":131,"sourceCode":"                    \"Adding disabled source (will be filtered by getEnabledSourceRoots): lang={}, scope={}, module={}, dir={}\",\n                    sourceRoot.language(),\n                    sourceRoot.scope(),\n                    sourceRoot.module().orElse(null),\n                    sourceRoot.directory());\n            return true;\n        }\n\n        // Normalize path for consistent duplicate detection (handles symlinks, relative paths)\n        Path normalizedDir = sourceRoot.directory().toAbsolutePath().normalize();\n        SourceKey key = new SourceKey(\n                sourceRoot.language(), sourceRoot.scope(), sourceRoot.module().orElse(null), normalizedDir);\n\n        if (!declaredSources.add(key)) {\n            String message = String.format(\n                    \"Duplicate enabled source detected: lang=%s, scope=%s, module=%s, directory=%s. \"\n                            + \"First enabled source wins, this duplicate is ignored.\",\n                    key.language(), key.scope(), key.module() != null ? key.module() : \"(none)\", key.directory());\n            LOGGER.warn(message);\n            result.getProblemCollector()\n                    .reportProblem(new DefaultModelProblem(\n                            message,\n                            Severity.WARNING,\n                            Version.V41,\n                            project.getModel().getDelegate(),\n                            -1,\n                            -1,\n                            null));\n            return false; // Don't add duplicate enabled source\n        }\n\n        LOGGER.debug(\n                \"Adding and tracking enabled source: lang={}, scope={}, module={}, dir={}\",\n                key.language(),\n                key.scope(),\n                key.module(),\n                key.directory());","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-core/src/main/java/org/apache/maven/project/SourceHandlingContext.java#L113-L149","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run mvn help:effective-pom and search for repeated <source> blocks with the same <directory> under the same build scope","Delete one of the duplicate <source> declarations, keeping the intended one","If both are conditionally needed, mark the less important one with <enabled>false</enabled> so it never competes","Remove legacy build-helper / add-test-source mojos that add a directory Maven 4 already tracks via <source>"],"exampleFix":"<!-- before: same directory declared twice for lang=java, scope=main -->\n<build>\n  <sources>\n    <source>\n      <directory>src/main/java</directory>\n      <language>java</language>\n    </source>\n    <source>\n      <directory>src/main/java</directory>\n      <language>java</language>\n      <module>com.example.app</module>\n    </source>\n  </sources>\n</build>\n\n<!-- after: single declaration; extra roots get their own directory -->\n<build>\n  <sources>\n    <source>\n      <directory>src/main/java</directory>\n      <language>java</language>\n    </source>\n    <source>\n      <directory>src/generated/java</directory>\n      <language>java</language>\n    </source>\n  </sources>\n</build>","handlingStrategy":"validation","validationCode":"# Lint POMs for duplicate source identities before building (bash)\npython3 - <<'EOF'\nimport xml.etree.ElementTree as ET, sys\nns = {'m': 'http://maven.apache.org/POM/4.0.0'}\nfor pom in sys.argv[1:]:\n    root = ET.parse(pom).getroot()\n    seen = set()\n    for s in root.iter('{http://maven.apache.org/POM/4.0.0}source'):\n        if s.findtext('m:enabled', 'true', ns) in ('true', 'True'):\n            key = (s.findtext('m:language', ns), s.findtext('m:directory', ns))\n            if key in seen: sys.exit(f\"duplicate enabled source {key} in {pom}\")\n            seen.add(key)\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare each source directory exactly once per language/scope combination in the POM","Remove legacy build-helper add-source goals that duplicate directories Maven 4 tracks natively","When merging sources from profiles, verify with mvn help:effective-pom that no directory repeats"],"tags":["maven","source-roots","maven4","model-building"],"backgroundTag":"duplicate-source-root-declaration","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}