#20314·conan

[bug] graph build-order build_args do not reproduce transitive dependency options

Author: AnastaZIukCreated Sep 5, 2026Updated Sep 8, 2026
Labelstype: bug

Describe the bug

Environment details:

  • Ubuntu latest
  • Python 3.12
  • Conan 2.32.0
  • Conan 2.33.0-dev from develop2 at e42971dc2952c83b7f5ab17cdf6bc49ac12b7c97

conan graph build-order returns a package node that cannot be recreated from its generated build_args and the same build and host profiles.

The minimal graph is:

app -> middle -> leaf

app sets these options through default_options:

python
{"middle/*:shared": True, "leaf/*:shared": True}

The full graph resolves middle against leaf:shared=True. The generated build_args for middle only preserve middle/*:shared=True:

--requires=middle/1.0 --build=middle/1.0 -o="middle/*:shared=True"

Evaluating those arguments with the same -pr:h=default -pr:b=default profiles changes leaf to its default shared=False. This also changes the package ID of middle:

leaf shared: True -> False
middle package_id: d70f758157f8902dfd15aa2b587fc96bb482f1e0 -> 0c1b59e1b79b09d06a2d6c704bf4c486b2c74832

The graph build-order documentation describes build_args as the "arguments needed for a conan install <args> to fire the build of this package". The default_options documentation also documents setting options for requirements with a reference pattern.

Why this is a bug

The build-order element identifies one concrete middle package ID and its concrete leaf dependency. Its build_args are attached to that exact element. Replaying those arguments with the same profiles must therefore resolve the same node.

Instead, one Conan result describes two incompatible configurations:

  • The element identifies middle:d70f... built against leaf:shared=True.
  • Its build_args resolve middle:0c1b... built against leaf:shared=False.

The missing value is not profile or command-line state. It originates in the root recipe and was already accepted when Conan computed the full graph. There is no additional profile argument that a caller can replay to recover it.

The default_options documentation recommends profiles for complex dependency configuration and describes precedence limitations. Neither changes this result. There is no precedence conflict in this linear graph. Conan has already resolved leaf:shared=True and emitted a concrete package ID for middle.

The generated command should recreate the package node it belongs to. It should either preserve leaf/*:shared=True or provide another self-consistent way to resolve the same dependency configuration and package ID.

Related issues

  • #14637 is the closest report. It was answered in terms of reapplying profile and command-line inputs. This reproducer explicitly reapplies identical build and host profiles. The missing input comes from the root recipe, so that workaround cannot restore it.
  • #16593 reported invalid option serialization in build_args and was fixed by #16594. This case is different because the generated arguments are syntactically valid but semantically incomplete.
  • #18096 reported missing build_args for editable nodes and was fixed by #18097. This case produces non-null arguments, but they resolve a different package node.

How to reproduce it

The complete reproducer is available at:

https://github.com/Devsh-Graphics-Programming/conan-repros/tree/main/build-order-transitive-options

It contains three recipes with no source files and no build logic. The Python script:

  1. Creates a temporary Conan home.
  2. Exports the three recipes.
  3. Computes the full build order for app/1.0.
  4. Extracts the generated build_args for middle/1.0.
  5. Evaluates those arguments with the same build and host profiles.
  6. Compares the option values and package IDs.

Run it with:

bash
python build-order-transitive-options/reproduce.py

Both tested versions reproduce the mismatch:

The output ends with:

build_args: --requires=middle/1.0 --build=middle/1.0 -o="middle/*:shared=True"
leaf shared: True -> False
middle package_id: d70f758157f8902dfd15aa2b587fc96bb482f1e0 -> 0c1b59e1b79b09d06a2d6c704bf4c486b2c74832
BUG REPRODUCED