{"record":{"id":"613704c05ca7a834","repo":"apache/maven","slug":"duplicated-lifecycle-phase-defined-in-but-a","errorCode":null,"errorMessage":"Duplicated lifecycle phase {}. Defined in {} but also in {}","messagePattern":"Duplicated lifecycle phase (.+?)\\. Defined in (.+?) but also in (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"impl/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java","lineNumber":116,"sourceCode":"    public Map<String, Lifecycle> getPhaseToLifecycleMap() {\n        if (logger.isDebugEnabled() && !lifecyclesPrinted) {\n            for (Lifecycle lifecycle : getLifeCycles()) {\n                logger.debug(\"Lifecycle {}\", lifecycle);\n            }\n            lifecyclesPrinted = true;\n        }\n\n        // If people are going to make their own lifecycles then we need to tell people how to namespace them correctly\n        // so that they don't interfere with internally defined lifecycles.\n\n        Map<String, Lifecycle> phaseToLifecycleMap = new HashMap<>();\n\n        for (Lifecycle lifecycle : getLifeCycles()) {\n            for (String phase : lifecycle.getPhases()) {\n                // The first definition wins.\n                Lifecycle original = phaseToLifecycleMap.put(phase, lifecycle);\n                if (original != null && logger.isWarnEnabled()) {\n                    logger.warn(\n                            \"Duplicated lifecycle phase {}. Defined in {} but also in {}\",\n                            phase,\n                            original.getId(),\n                            lifecycle.getId());\n                }\n            }\n            if (lifecycle.getDelegate() != null) {\n                for (org.apache.maven.api.Lifecycle.Alias alias :\n                        lifecycle.getDelegate().aliases()) {\n                    Lifecycle original = phaseToLifecycleMap.put(alias.v3Phase(), lifecycle);\n                    if (original != null && logger.isWarnEnabled()) {\n                        logger.warn(\n                                \"Duplicated lifecycle phase {}. Defined in {} but also in {}\",\n                                alias.v3Phase(),\n                                original.getId(),\n                                lifecycle.getId());\n                    }\n                }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java#L98-L134","documentation":"DefaultLifecycles builds a phase-to-lifecycle map across all installed lifecycles (default, clean, site, plus any contributed by packaging/extension plugins). When two lifecycles define the same phase, the first registration wins and this warning names both lifecycle ids; later lookups for that phase resolve to the first lifecycle only. The check also covers the v3 aliases of each lifecycle.","triggerScenarios":"A custom lifecycle contributed by a core extension or packaging plugin declares a phase id that the default lifecycle (or an earlier-loaded custom lifecycle) already owns - e.g. redefining 'compile' or 'package'.","commonSituations":"In-house packaging plugins reusing standard phase names to 'override' them; multiple custom lifecycle extensions loaded together; upgrading a lifecycle extension that grew new phases that clash.","solutions":["Rename the custom lifecycle's phases to a unique, namespaced id (e.g. acme-compile instead of compile)","Remove the custom phase that duplicates the standard one and bind goals to the standard phase instead","List loaded lifecycles (mvn -X) to find which two lifecycle ids collide, then fix the one you control"],"exampleFix":"<!-- before (custom lifecycle hijacks a standard phase) -->\n<lifecycle>\n  <id>acme</id>\n  <phases>\n    <phase>compile</phase>\n  </phases>\n</lifecycle>\n<!-- after (namespaced phase id) -->\n<lifecycle>\n  <id>acme</id>\n  <phases>\n    <phase>acme-compile</phase>\n  </phases>\n</lifecycle>","handlingStrategy":"validation","validationCode":"// in the lifecycle extension's tests: assert no phase collides with standard lifecycles\nSet<String> standard = Set.of(/* default+clean+site phases */ \"compile\", \"test\", \"package\", \"verify\", \"install\", \"deploy\", \"clean\", \"site\");\nfor (String phase : myLifecycle.getPhases()) {\n    if (standard.contains(phase)) {\n        throw new IllegalStateException(\"Custom lifecycle redefines standard phase: \" + phase);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Namespace custom phase ids (acme-compile, not compile)","Test custom lifecycles against the full default lifecycle set in the plugin's IT suite","Review loaded lifecycles with mvn -X whenever you add a lifecycle extension"],"tags":["lifecycle","custom-lifecycle","phase-conflict","packaging"],"backgroundTag":"duplicate-phase-definition","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}