garbage-collection internals are not documented / toString produces store path without context
Problem
I'm using home-manager for my ssh secrets... which I know I shouldn't be doing but this is a documentation issue so my use-case doesn't really matter.
Anyways there is this option for ssh identities
My identity file is in my flake and I don't want to use an absolute path to the directory my flake is in (obviously), Which is why I did this instead.
programs.ssh = {
matchBlocks = {
"aur.archlinux.org" = {
identityFile = toString ../../secrets/ssh/aur;
user = "aur";
};
"github.com" = {
identityFile = toString ../../secrets/ssh/github;
user = "git";
};
};
};
Surprisingly after every garbage collect my git push stops working
no such identity: /nix/store/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-source/secrets/ssh/github: No such file or directory
[email protected]: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
This behavior is weird because it definitely works in e.g. my hyprland config where I use ${pkgs.something} all the time and it never gets garbage collected. Also from what I've read in the nix docs a garbage collect should never change my system state.
This definitely did change my system.
Even after searching specifically for this issue I couldn't come across any information on how the garbage collectors decides which "relative path derivations" it keeps and which ones it doesn't.
I suspect the toString is somehow deleting that information
If this is actually a bug and not a documentation issue let me known I'll change the title.
TLDR
The garbage collector collects the ../../file derivation in this expression toString ../../file and there's no documentation explaining why.
Checklist
-
[x] checked latest Nix manual ([source])
this search yields a bunch of unhelpful pages trying to explain the nix-collect-garbage command which is not what I need at all. -
[ ] checked open documentation issues and pull requests for possible duplicates (not thoroughly)
Priorities
Add :+1: to issues you find important.
Technically this is about the expression language semantics more so than the store-level garbage collection behavior. I honestly don't know how we should address this in the manual. Where would you expect to find this information?
As for the behavior, toString traditionally did not need to return a string with a string context, because e.g. toString /home == "/home".
It seems likely that you're using Flakes, which makes this behavior easy to encounter by putting sources in the store first.
Based on the discussion in #8428, I think the best way to prevent this mistake is not to create path values (what you referred to by relative paths, iiuc) that refer to the store.
Regardless, the toString documentation is lacking.