Assertion failure in nix::flake::fetchOrSubstituteTree
when an input-addressed store path is a path-type flake input #529
Labels
No labels
Affects/CppNix
Affects/Nightly
Affects/Only nightly
Affects/Stable
Area/build-packaging
Area/cli
Area/evaluator
Area/fetching
Area/flakes
Area/language
Area/lix ci
Area/nix-eval-jobs
Area/profiles
Area/protocol
Area/releng
Area/remote-builds
Area/repl
Area/repl/debugger
Area/store
bug
Context
contributors
Context
drive-by
Context
maintainers
Context
RFD
crash 💥
Cross Compilation
devx
docs
Downstream Dependents
E/easy
E/hard
E/help wanted
E/reproducible
E/requires rearchitecture
imported
Language/Bash
Language/C++
Language/NixLang
Language/Python
Language/Rust
Needs Langver
OS/Linux
OS/macOS
performance
regression
release-blocker
stability
Status
blocked
Status
invalid
Status
postponed
Status
wontfix
testing
testing/flakey
Topic/Large Scale Installations
ux
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lix-project/lix#529
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Describe the bug
This can be triggered by naming your derivation "source" and later import the built result in a flake. This is because a derivation named "source" will not be copied to store when it's imported:
if (!storePath || storePath->name() != "source" || !store->isValidPath(*storePath)) {
And store paths are computed differently for built outputs.
Why am I doing this?
Because I don't want to create a copy of the input when it's already in the store, it slows down evaluation and take unnecessary disk space.
Proposal
Remove this assertion, and remove the
== "source"
check as well. Avoid all store to store copies.Note I somehow can't reliably reproduce this, perhaps due to caching or some other oddities.
Here is a stack trace of the assertion failure:
Do you still have the core dump? Can you grab some info from it?
Here's how you can get debug info:
then inside the gdb, put the path resulting from
nix derivation show /nix/store/83ac3g127apfhick95hlrjd5s2wgd5zf-lix-2.91.0pre20240820_ed51a17 | jq -r '.[] | .env.src'
asdir
so you have sources for the Lix:For example,
dir /nix/store/fdlsflkgdslglkjg-source
What I would like is to know the output of:
I am not really sure how that assertion gets triggered. It implies that we can have a fetcher grab an input (and do so successfully) with a different narHash attribute than the one in
originalRef.input
, which I think is the one in the lock file, without first throwing an error that the hash did not match.That definitely should be a bug, but I don't know what we can do about it without a reproducer.
I did notice a possible soundness bug in the equals operator of
Input
, which is that if you have two path inputs with differentparent
but the same attrs, they will compare as equal, but I am not sure if this is possible to trigger. The inference I can draw from this is that maybe the fetcher cache could have mixed up two path inputs? But this is no smoking gun.sorry I gc'd and doesn't have the original executable anymore. maybe if it happens again i can get the info for you.
@jade
This is not what this assertion checks.
!originalRef.input.getNarHash()
is false, because this input has a narHash, so it is actually this part that fails:tree.storePath == originalRef.input.computeStorePath(*state.store)
This is checking to make sure the input's store path is content addressable, which will not be true if the input is the output of a derivation.
And normally nix copies the store path if you use the output of a derivation as input, so the result of the copy will have a content addressable store path. That is unless you name the derivation
"source"
. Basically what I already explained in my OP.Hm. It's an input-addressed derivation that is used as a flake input? That's creative. Yeah I can imagine nobody tried that yet.
Thanks XD
For context I have a bunch of patches on top of upstream nixpkgs, which is applied with
applyPatches
and the result stored in nix store. I use the same patched version of nixpkgs system wide, by putting it inregistry.json
, as well asNIX_PATH
.This works, but every time I evaluate something, nix copies the patched version of nixpkgs from store to store, which is slow, and feels dumb. Then I discovered, by reading the code, I can sort of avoid that by naming the patched nixpkgs derivation "source". Except doing so sometimes triggers this assertion failure.
Assertion failure into Assertion failure innix::flake::fetchOrSubstituteTree
nix::flake::fetchOrSubstituteTree
when an input-addressed store path is a path-type flake input