Fixing “Illegal path references in fixed-output derivation” in Nix
The other day I was working with fixed-output derivations. After copying several files to $out
, I was facing a “Illegal path references in fixed-output derivation error”. The only helpful reference on the internet I could find was the Nix source code on GitHub.
It took me a while to figure out what’s going on. You get this error when your fixed-output derivation places something in $out
which contains a Nix store path! This can for example be a script with a (patched) shebang that (accidentally) landed there.
What happened in my case
I was packaging Limine and the ./bootstrap
script performs several git clone
invocations. Each git clone
invocation creates .<repository>/git/hooks
with a few example hooks. Each hook is a shell script starting with a shebang.. and Git automatically puts the binaries it finds in its PATH into the shebang, which on my NixOS system were all coming from the Nix store. That was a fun thing to debug!
The solution in that specific case is to remove all **/.git/hooks
directories in that fixed-output derivation. 😂
5 Comments
Rutherther · 2024-06-05 at 22:00
Hello Philipp,
I am thinking about your solution. It doesn’t seem to me your solution would be very robust. Since there should never be nix paths in the fixed output derivation, why not remove the source of the problems? In this case the source of the problems is fixup phase which does this shebang patching. Setting `dontFixup = true;` will disable it
Philipp Schuster · 2024-06-11 at 18:54
Hey! It is highly specific on the use-case. In my specific case, the git hooks were just junk, so removing them was correct. Sometimes however `dontFixup `true` or `dontPatchShebangs = true` might be necessary. The important take-away here is that if you get this error, you really have to check out where Nix store paths are in `$out` and if you need them at that point.
Ben Millwood · 2024-10-11 at 03:09
This actually isn’t shebang patching — `git clone` writes the example hooks like that in the first place. I guess it does something like $(realpath $(which bash)) and then writes that as the shebang line.
dns_issue · 2024-07-23 at 08:15
Haha, thanks for the post. Helped me fix my issue. I had the shebang line referencing bash from the /nix/store. I replaced it to: /etc/profiles/per-user//bin/bash. And it finally worked. Thanks man
Ben Millwood · 2024-10-11 at 03:06
I just created https://github.com/NixOS/nix/issues/11673 to talk about how to make this error easier to debug. I found it was extra painful in my case because I was doing `nix-build –keep-failed` but couldn’t find any path references in the build directory: it turned out I was writing them directly to `$out`, which isn’t the directory that’s kept. Lesson for me to do stuff in the build directory and then just copy it, as it makes `–keep-failed` more useful for stuff like this 🙂