-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Describe the bug
Consider the following setup:
- Flake
foocontains a subflake ininputs.foo-subflakedefined via a relative path. This works correctly. - Flake
barhasfooas an input. Bothfooandfoo-subflakeresolve correctly. - Flake
erichasbaras an input. At this level, Nix fails to generate flake.lock forbar, becausefoo-subflakeis resolved against thebarsource tree instead offoo's tree.
Steps To Reproduce
I created a minimal repository demonstrating the problem: https://github.com/yunfachi/broken-nix-subflakes/
git clone https://github.com/yunfachi/broken-nix-subflakes.git
cd broken-nix-subflakes
./set-local-path.sh
cd user-of-library-that-depends-on-library
nix flake updateExpected behavior
Relative path inputs inside nested flakes should always be resolved relative to the flake they belong to, regardless of whether mustRefetch is true or false.
Additional context
I tried to debug the issue, and the problem seems to come from this part of the Nix source code:
https://github.com/NixOS/nix/blob/7448aedd74e28174bfa33aad0d148c0070c86dfb/src/libflake/flake.cc#L700C29-L701C113
At this point, the sourcePath passed into computeLocks() appears to belong to the parent flake (for example, bar) instead of the flake that actually owns the relative input (for example, foo). Because of this, the relative path inside foo is resolved against bar's directory, which breaks nested subflake resolution.
If I replace:
if (mustRefetch) {with:
if (true) {so that refetch always happens, everything works correctly and the relative path resolves as expected. This suggests that the correct sourcePath is only used during refetch, while the non-refetch path uses an incorrect base directory.
Add 👍 to issues you find important.