#20321·conan

[bug] graph info rejects an acyclic compiler bootstrap graph

Author: AnastaZIukCreated Sep 8, 2026Updated Sep 11, 2026
Labelsstage: triaging

Describe the bug

Environment details:

  • Ubuntu 24.04 on GitHub Actions (ubuntu-latest)
  • Python 3.12
  • Conan 2.32.0
  • Conan 2.33.0-dev from develop2 at 22d18a3e4f478f4def5cba238c320dc5ddf1193d

Also reproduced locally on Windows with both Conan versions.

conan graph info reports a dependency loop for a graph that conan graph build-order --order-by=configuration orders successfully with the same recipes, profiles, and empty binary cache.

Consider a bootstrap package that downloads prebuilt compiler tools, verifies their checksums, and assembles a toolchain. That toolchain builds LLVM, Clang, and their dependencies, including Z3, from source. The resulting compiler is then used to build consumer libraries. A consumer can also need Z3, directly or through an LLVM SDK dependency.

The repro reduces this setup to three metadata-only recipes:

  • clang-bootstrap/1.0 has no dependencies.
  • clang-hybrid/1.0 requires z3/1.0.
  • z3/1.0 has compiler settings.

The build profile selects Clang 21 and supplies clang-bootstrap through [tool_requires]. The host profile selects Clang 22 and supplies clang-hybrid. Tool requirements use their default visibility. The consumer requires only z3/1.0.

Arrows below mean "requires":

z3 [host, Clang 22]
  -> clang-hybrid [build, Clang 21]
     -> z3 [build, Clang 21]
        -> clang-bootstrap [build]

clang-hybrid also directly requires clang-bootstrap as a build tool.

Why this is a bug

Conan already computes a valid order for this exact set of package configurations.

The two Z3 nodes have the same recipe revision but different package IDs. The compiler's Z3 uses the bootstrap and does not depend on the hybrid. Only the consumer's Z3 requires the hybrid. Every dependency can therefore be satisfied in this order:

clang-bootstrap -> z3 [Clang 21] -> clang-hybrid -> z3 [Clang 22]

graph build-order --order-by=configuration returns this order. The repro verifies the two distinct Z3 package IDs and checks that every dependency precedes its consumer.

Grouping both Z3 configurations into one recipe node produces z3 -> clang-hybrid -> z3. The compiler must be processed between the two Z3 configurations, so failure of --order-by=recipe alone is expected.

The bug is that graph info rejects the same dependency setup as ill-formed and impossible to install, despite Conan having computed a valid order for it. In Conan 2.32.0, InstallGraph defaults to recipe grouping, and install_binaries() uses that default.

graph info should accept this graph, and one conan install --build=missing should be able to process its packages in the order above. Preserving dependencies between package configurations would allow configurations of the same recipe to be processed at different stages. This would handle this class of graphs without compiler-specific rules or changes to the recipe dependencies.

How to reproduce it

The complete reproducer contains three recipes with no source files or build logic, two profiles, and a Python script.

With Conan installed and conan on PATH, run from the repro repository root:

bash
python compiler-bootstrap-cycle/reproduce.py

The script creates a temporary Conan home, exports the recipes, and runs the graph commands with remotes disabled. No packages are downloaded or built, and no compiler installation is needed. Temporary Conan state is removed on exit.

Both Ubuntu jobs reproduce the failure:

The script reports:

graph build-order --order-by=configuration: OK
graph build-order --order-by=recipe: LOOP
graph info: LOOP
BUG REPRODUCED without building any packages

The script succeeds only when the configuration order is valid and both failing commands report a dependency loop.