{"record":{"id":"34047f2858e40b95","repo":"quarkusio/quarkus","slug":"failed-to-normalize-the-dependency-graph","errorCode":null,"errorMessage":"Failed to normalize the dependency graph","messagePattern":"Failed to normalize the dependency graph","errorType":"exception","errorClass":"AppModelResolverException","httpStatus":null,"severity":"error","filePath":"independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyTreeResolver.java","lineNumber":383,"sourceCode":"            if (dep == null || dep.isFlagSet(DependencyFlags.VISITED)) {\n                continue;\n            }\n            dep.setFlags(DependencyFlags.VISITED);\n            dep.clearFlag(DependencyFlags.RELOADABLE);\n            clearReloadableFlag(dep);\n        }\n    }\n\n    private DependencyNode normalize(RepositorySystemSession session, DependencyNode root) throws AppModelResolverException {\n        final DependencyGraphTransformationContext context = new SimpleDependencyGraphTransformationContext(session);\n        try {\n            // add conflict IDs to the added deployments\n            root = new ConflictMarker().transformGraph(root, context);\n            // resolves version conflicts\n            root = new ConflictIdSorter().transformGraph(root, context);\n            root = session.getDependencyGraphTransformer().transformGraph(root, context);\n        } catch (RepositoryException e) {\n            throw new AppModelResolverException(\"Failed to normalize the dependency graph\", e);\n        }\n        return root;\n    }\n\n    private DependencyNode resolveRuntimeDeps(CollectRequest request) throws AppModelResolverException {\n        var session = resolver.getSession();\n        if (!CONVERGED_TREE_ONLY && collectReloadableModules) {\n            final DefaultRepositorySystemSession mutableSession;\n            mutableSession = new DefaultRepositorySystemSession(resolver.getSession());\n            mutableSession.setDependencyGraphTransformer(new DependencyGraphTransformer() {\n\n                @Override\n                public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransformationContext context)\n                        throws RepositoryException {\n                    final Map<DependencyNode, DependencyNode> visited = new IdentityHashMap<>();\n                    for (DependencyNode c : node.getChildren()) {\n                        walk(c, visited);\n                    }","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyTreeResolver.java#L365-L401","documentation":"After injecting deployment dependencies, normalize() runs the Maven Resolver's graph transformers (ConflictMarker, ConflictIdSorter, then the session's DependencyGraphTransformer) to produce a conflict-resolved graph. Any RepositoryException raised by these transformers (inconsistent conflict ids, cyclic graph issues, transformer-internal problems) is wrapped in this AppModelResolverException.","triggerScenarios":"normalize(originalSession, root) is called from resolve() after deployment dependency injection; the injected graph causes a transformer to fail — most often due to malformed conflict id state after manual node injection, dependency cycles, or inconsistent optional/scope metadata produced by earlier resolution steps.","commonSituations":"Dependency cycles among extensions or between application modules and extensions; workspace-built extension versions producing self-referential graphs; Quarkus bootstrap bugs triggered by unusual graphs (rare, often reported upstream); heavily customized session dependency graph transformers.","solutions":["Run 'mvn dependency:tree -Dverbose' to detect dependency cycles or mediation oddities among your extensions and break any cycle (refactor extension/module structure).","Remove snapshot/workspace local builds of extensions and test with released platform versions to rule out a corrupted graph.","Upgrade Quarkus to the latest patch version — graph normalization edge cases are fixed frequently.","Capture the cause RepositoryException and the full pom/dependency list and report a Quarkus issue if the graph looks ordinary."],"exampleFix":"// before: module A and extension B depend on each other (cycle)\ncom.acme:lib-a -> io.quarkus.ext:ext-b-deployment\nio.quarkus.ext:ext-b-deployment -> com.acme:lib-a\n// after: break the cycle by extracting shared code\ncom.acme:lib-a -> com.acme:lib-common\nio.quarkus.ext:ext-b-deployment -> com.acme:lib-common","handlingStrategy":"validation","validationCode":"// detect cycles in your module/extension graph before the build\n// mvn dependency:tree -Dverbose; fail if an artifact is its own ancestor\nstatic void assertNoCycles(Map<String, Set<String>> deps) {\n    for (String root : deps.keySet()) {\n        Set<String> seen = new HashSet<>();\n        dfs(root, deps, seen);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    quarkusBuild();\n} catch (AppModelResolverException e) {\n    if (e.getMessage().contains(\"Failed to normalize the dependency graph\")) {\n        throw new IllegalStateException(\"Check dependency cycles / conflicting extensions; cause: \" + e.getCause(), e);\n    }\n    throw e;\n}","preventionTips":["Avoid circular dependencies between application modules and extensions.","Use released platform-aligned extension versions rather than ad-hoc local snapshots.","Keep Quarkus updated; normalization bugs are fixed in patch releases.","Inspect dependency:tree -Dverbose output when graphs get complex."],"tags":["maven","dependency-graph","conflict-resolution"],"backgroundTag":"dependency-graph-normalization-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}