Broken nix-env, no rollback possible


I’m using unstable, and recently upgraded both system (sudo nixos-rebuild switch --upgrade) and user profile (home-manager switch). After a couple days, since everything was working fine and I was running low on space, I ran the garbage collector (nix-collect-garbage -d and sudo nix-collect-garbage -d). But this morning I noticed my system was broken:

❯ nix-env -iA nixos.hello                                                               
error: syntax error, unexpected $end, at /nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix:1:1
❯ cat /nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix

Someone posted about this issue already: Unable to update NixOS unstable but got no answer. I tried what was suggested in the post just in case it didn’t work:

❯ sudo nix-store --verify --check-contents --repair
[sudo] password for little-dude: 
reading the Nix store...
checking path existence...
checking hashes...
path '/nix/store/gw6ni479638lifwxmlq4v9z31a06hwqp-user-environment.drv' was modified! expected hash 'sha256:09qnhg11ijpwqazg2al14rb7j0ky053dwxync8qddla1y9q0vw3s', got 'sha256:0ip26j2h11n1kgkz36rl4akv694yz65hr72q4kv4b3lxcbi65b3p'
error: cannot repair path '/nix/store/gw6ni479638lifwxmlq4v9z31a06hwqp-user-environment.drv'
path '/nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix' was modified! expected hash 'sha256:184h00i4x0ydv6fwv69fgsg33wyja9d0qqzxr4ckckxpw9m373wm', got 'sha256:0ip26j2h11n1kgkz36rl4akv694yz65hr72q4kv4b3lxcbi65b3p'
error: cannot repair path '/nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix'
warning: not all errors were fixed

I found this IRC conversation, where @ottidmes suggests that in order to fix the corrupted paths (/nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix and /nix/store/gw6ni479638lifwxmlq4v9z31a06hwqp-user-environment.drv in my case), we need to:

  1. find and delete their root
  2. run the gc to remove the paths
  3. rebuild everything with sudo nixos-rebuild switch --upgrade and home-manager switch

For step 1. the root is the same for both paths:

❯ nix-store --query --roots /nix/store/largfl1x1qrwfvvprazn8jqg5ds43dak-env-manifest.nix
/nix/var/nix/profiles/per-user/little-dude/profile-32-link -> /nix/store/h9aljgiz1ly53c3g1l5c9a1n9p4awkg0-user-environment
❯ nix-store --query --roots /nix/store/gw6ni479638lifwxmlq4v9z31a06hwqp-user-environment.drv
/nix/var/nix/profiles/per-user/little-dude/profile-32-link -> /nix/store/h9aljgiz1ly53c3g1l5c9a1n9p4awkg0-user-environment

However I’m afraid of going further and would like confirmation that this is the right approach:

rm -f /nix/var/nix/profiles/per-user/little-dude/profile-32-link
sudo nix-collect-garbage -d  
nix-collect-garbage -d  
sudo nixos-rebuild switch --upgrade
home-manager switch

In particular, since I garbage collected my user profiles, I only have one left, so I’m not sure what will happen when I call the garbage collector… Will home-manager still be there at all?

@clever on IRC helped my going through this.

To sum up, the fix was indeed to delete the remaining profile:

rm \
    /nix/var/nix/profiles/per-user/little-dude/profile \

But then to NOT run the gc. Since I’m using home-manager, all I had to do was call home-manager to re-create everything. Without a profile, it’s not in the PATH though:

$ home-manger switch
zsh: command not found: home-manager

But it’s easy enough to find in the store:

ls -l /nix/store/*/bin/home-manager