Describe the bug
I'm seeing error: path <x> is not valid when attempting to copy from a local binary cache (ie. nix copy --all --from file://). I can't easily reproduce it on another machine, but I do have a couple of data points which I think should suffice.
Note there's a related (closed) issue at #9052. Over there @a-h seemed to experience the same issue as I'm seeing which I suspect to be a different bug than the one originally reported.
Crucially, this bug manifests when copying from a local binary cache. As one does in 2026 I've asked Claude and it claims to have identified the bug. Being unfamiliar with the Nix codebase/C++ I can't easily tell whether it's right but the parts I do follow make sense to me.
These two comments are relevant:
#9052 (comment)
#9052 (comment)
Note this remark by @a-h:
the copy operation looks like it's working through the alphabetic ordering of the paths, instead of following the dependency graph order (as the recursive verification does).
Claude analysis
Claims 1 and 3 below seem fair to me, 2 would be the root cause and I don't understand the internals well enough to tell whether it really makes sense.
(Verbatim Claude Sonnet output follows)
LocalBinaryCacheStore::queryAllValidPaths() returns x-named paths
("<hash>-x") because only the hash part is known from .narinfo
filenames. This caused three interacting failures:
1. dstStore.queryValidPaths(x-named) finds nothing in the local SQLite
database, so ALL paths appear missing — even those already present
under their real names.
2. srcStore.topoSortPaths(x-named) calls queryPathInfo(<hash>-x) which
correctly resolves narinfos and returns real-named references, but
topoSort then checks items.count(real-named-ref) against a set of
x-named items — always 0 — so no dependency edges are found and the
sort produces an arbitrary ordering.
3. RemoteStore::addMultipleToStore() (protocol >= 1.32) sends paths to
the daemon in pathsToCopy order. The daemon processes them
sequentially with addToStore(); when a dependent arrives before its
reference, registerValidPaths() calls queryValidPathId() on a path
not yet in SQLite and throws "path '...' is not valid".
Other backends like ssh:// work because RemoteStore::queryAllValidPaths()
fetches real names from the remote daemon's SQLite, so topoSortPaths
correctly orders them.
Fix: after building pathsToCopy (which already carries real destination
path names and references), re-sort it topologically using those real
names. This produces the correct dependency order regardless of what
srcStore.topoSortPaths returned.
Metadata
Was able to trigger on Nix 2.34.5.
Add 👍 to issues you find important.
Describe the bug
I'm seeing
error: path <x> is not validwhen attempting to copy from a local binary cache (ie.nix copy --all --from file://). I can't easily reproduce it on another machine, but I do have a couple of data points which I think should suffice.Note there's a related (closed) issue at #9052. Over there @a-h seemed to experience the same issue as I'm seeing which I suspect to be a different bug than the one originally reported.
Crucially, this bug manifests when copying from a local binary cache. As one does in 2026 I've asked Claude and it claims to have identified the bug. Being unfamiliar with the Nix codebase/C++ I can't easily tell whether it's right but the parts I do follow make sense to me.
These two comments are relevant:
#9052 (comment)
#9052 (comment)
Note this remark by @a-h:
Claude analysis
Claims 1 and 3 below seem fair to me, 2 would be the root cause and I don't understand the internals well enough to tell whether it really makes sense.
(Verbatim Claude Sonnet output follows)
Metadata
Was able to trigger on Nix 2.34.5.
Add 👍 to issues you find important.