{"record":{"id":"6e6fc004494fa09d","repo":"quarkusio/quarkus","slug":"cycle-detected-in-relativeorder-declarations-invo","errorCode":null,"errorMessage":"Cycle detected in @RelativeOrder declarations involving s: ","messagePattern":"Cycle detected in @RelativeOrder declarations involving s: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/signals/deployment/src/main/java/io/quarkus/signals/deployment/TopologicalSort.java","lineNumber":90,"sourceCode":"        }\n\n        List<String> sorted = new ArrayList<>();\n        while (!queue.isEmpty()) {\n            String node = queue.poll();\n            sorted.add(node);\n            for (String neighbor : graph.get(node)) {\n                int newDegree = inDegree.get(neighbor) - 1;\n                inDegree.put(neighbor, newDegree);\n                if (newDegree == 0) {\n                    queue.add(neighbor);\n                }\n            }\n        }\n\n        if (sorted.size() != allIds.size()) {\n            Set<String> remaining = new HashSet<>(allIds);\n            remaining.removeAll(sorted);\n            throw new IllegalStateException(\n                    \"Cycle detected in @RelativeOrder declarations involving \" + componentTypeName + \"s: \" + remaining);\n        }\n\n        return sorted;\n    }\n\n}\n","sourceCodeStart":72,"sourceCodeEnd":98,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/signals/deployment/src/main/java/io/quarkus/signals/deployment/TopologicalSort.java#L72-L98","documentation":"Components are ordered with a topological sort of their @RelativeOrder declarations. When the relative-order constraints form a cycle (A before B before A), no total order exists and the build fails with the set of ids stuck in the cycle.","triggerScenarios":"Two or more SPI component beans whose @RelativeOrder(before/after) constraints reference each other circularly, or a self-reference.","commonSituations":"Two library enrichers each declaring they come after the other, or a user component wedged between two mutually ordered components.","solutions":["Break the cycle by removing or relaxing one @RelativeOrder(before/after) declaration among the ids listed in the message.","Use only 'after' (or only 'before') edges in your own components to reduce conflict risk.","If the cycle comes from libraries, override ordering by giving your bean explicit non-cyclic constraints or update/remove an extension."],"exampleFix":"// before\n@Identifier(\"a\") @RelativeOrder(after = \"b\") class A ...\n@Identifier(\"b\") @RelativeOrder(after = \"a\") class B ...\n\n// after\n@Identifier(\"a\") class A ...\n@Identifier(\"b\") @RelativeOrder(after = \"a\") class B ...","handlingStrategy":"validation","validationCode":"// Detect cycles in before/after edges before build:\nMap<String,Set<String>> edges = ...; // 'after' constraints\n// run Kahn's algorithm; if sorted.size() < nodes.size() -> cycle","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use one-directional ordering constraints (only 'after') for your components.","Keep @RelativeOrder minimal; rely on defaults when order does not matter.","Document ordering intent per component to avoid mutual before/after declarations."],"tags":["quarkus","ordering","cycle","build-time"],"backgroundTag":"cyclic-dependency-ordering","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"}