diff --git a/modules/launchd/default.nix b/modules/launchd/default.nix index 5943188e..8754daa1 100644 --- a/modules/launchd/default.nix +++ b/modules/launchd/default.nix @@ -43,7 +43,31 @@ let }; }; - toAgent = config: pkgs.writeText "${config.Label}.plist" (toPlist { escape = true; } config); + # mutateConfig calls /bin/sh with /bin/wait4path to wait for /nix/store before + # running the original Program and ProgramArguments. This is intentional to + # fix the issue where launchd starts the agent before /nix/store is ready + # (before the Nix store is mounted.) + mutateConfig = + cnf: + let + args = + lib.optional (cnf.Program != null) cnf.Program + ++ lib.optionals (cnf.ProgramArguments != null) cnf.ProgramArguments; + in + (removeAttrs cnf [ + "Program" + "ProgramArguments" + ]) + // { + ProgramArguments = [ + "/bin/sh" + "-c" + "/bin/wait4path /nix/store && exec ${lib.escapeShellArgs args}" + ]; + }; + + toAgent = + config: pkgs.writeText "${config.Label}.plist" (toPlist { escape = true; } (mutateConfig config)); agentPlists = lib.mapAttrs' (n: v: lib.nameValuePair "${v.config.Label}.plist" (toAgent v.config)) ( lib.filterAttrs (n: v: v.enable) cfg.agents diff --git a/modules/misc/news/2026/01/2026-01-27_21-41-51.nix b/modules/misc/news/2026/01/2026-01-27_21-41-51.nix new file mode 100644 index 00000000..a511bf72 --- /dev/null +++ b/modules/misc/news/2026/01/2026-01-27_21-41-51.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + time = "2026-01-27T21:41:51+00:00"; + condition = pkgs.stdenv.hostPlatform.isDarwin && config.launchd.enable; + message = '' + + The `launchd` module now ensures that the Nix store is mounted and + available before starting any agents. This improves reliability on macOS + where `launchd` might otherwise attempt to start agents before the Nix + store is ready. + ''; +} diff --git a/tests/modules/launchd/expected-agent.plist b/tests/modules/launchd/expected-agent.plist index 4db6dcc1..4d5f5366 100644 --- a/tests/modules/launchd/expected-agent.plist +++ b/tests/modules/launchd/expected-agent.plist @@ -17,9 +17,9 @@ Background ProgramArguments - /some/command - --with-arguments - foo + /bin/sh + -c + /bin/wait4path /nix/store && exec /some/command --with-arguments foo UnrecognizedByHomeManager should make it to the resulting plist diff --git a/tests/modules/programs/aerospace/aerospace-service-expected.plist b/tests/modules/programs/aerospace/aerospace-service-expected.plist index 4a44448c..d85708ff 100644 --- a/tests/modules/programs/aerospace/aerospace-service-expected.plist +++ b/tests/modules/programs/aerospace/aerospace-service-expected.plist @@ -6,8 +6,12 @@ Label org.nix-community.home.aerospace - Program - /nix/store/00000000000000000000000000000000-aerospace/Applications/AeroSpace.app/Contents/MacOS/AeroSpace + ProgramArguments + + /bin/sh + -c + /bin/wait4path /nix/store && exec /nix/store/00000000000000000000000000000000-aerospace/Applications/AeroSpace.app/Contents/MacOS/AeroSpace + RunAtLoad StandardErrorPath diff --git a/tests/modules/programs/git/expected-agent-daily.plist b/tests/modules/programs/git/expected-agent-daily.plist index d96a936a..1ea3a384 100644 --- a/tests/modules/programs/git/expected-agent-daily.plist +++ b/tests/modules/programs/git/expected-agent-daily.plist @@ -6,13 +6,9 @@ org.nix-community.home.git-maintenance-daily ProgramArguments - @git@/bin/git - for-each-repo - --keep-going - --config=maintenance.repo - maintenance - run - --schedule=daily + /bin/sh + -c + /bin/wait4path /nix/store && exec @git@/bin/git for-each-repo --keep-going '--config=maintenance.repo' maintenance run '--schedule=daily' StartCalendarInterval diff --git a/tests/modules/programs/git/expected-agent-hourly.plist b/tests/modules/programs/git/expected-agent-hourly.plist index 99ade743..90780fb8 100644 --- a/tests/modules/programs/git/expected-agent-hourly.plist +++ b/tests/modules/programs/git/expected-agent-hourly.plist @@ -6,13 +6,9 @@ org.nix-community.home.git-maintenance-hourly ProgramArguments - @git@/bin/git - for-each-repo - --keep-going - --config=maintenance.repo - maintenance - run - --schedule=hourly + /bin/sh + -c + /bin/wait4path /nix/store && exec @git@/bin/git for-each-repo --keep-going '--config=maintenance.repo' maintenance run '--schedule=hourly' StartCalendarInterval diff --git a/tests/modules/programs/git/expected-agent-weekly.plist b/tests/modules/programs/git/expected-agent-weekly.plist index dbcdac9b..e2c8a3f9 100644 --- a/tests/modules/programs/git/expected-agent-weekly.plist +++ b/tests/modules/programs/git/expected-agent-weekly.plist @@ -6,13 +6,9 @@ org.nix-community.home.git-maintenance-weekly ProgramArguments - @git@/bin/git - for-each-repo - --keep-going - --config=maintenance.repo - maintenance - run - --schedule=weekly + /bin/sh + -c + /bin/wait4path /nix/store && exec @git@/bin/git for-each-repo --keep-going '--config=maintenance.repo' maintenance run '--schedule=weekly' StartCalendarInterval diff --git a/tests/modules/programs/nh/darwin/launchd.plist b/tests/modules/programs/nh/darwin/launchd.plist index efdb65d2..987f2105 100644 --- a/tests/modules/programs/nh/darwin/launchd.plist +++ b/tests/modules/programs/nh/darwin/launchd.plist @@ -6,9 +6,9 @@ org.nix-community.home.nh-clean ProgramArguments - @nh@/bin/nh - clean - user + /bin/sh + -c + /bin/wait4path /nix/store && exec @nh@/bin/nh clean user StartCalendarInterval diff --git a/tests/modules/programs/opencode/web-service.plist b/tests/modules/programs/opencode/web-service.plist index d7247b10..698a8730 100644 --- a/tests/modules/programs/opencode/web-service.plist +++ b/tests/modules/programs/opencode/web-service.plist @@ -15,20 +15,9 @@ Background ProgramArguments - @opencode@/bin/opencode - web - --hostname - 0.0.0.0 - --port - 4096 - --mdns - --cors - https://example.com - --cors - http://localhost:3000 - --print-logs - --log-level - DEBUG + /bin/sh + -c + /bin/wait4path /nix/store && exec @opencode@/bin/opencode web --hostname 0.0.0.0 --port 4096 --mdns --cors https://example.com --cors http://localhost:3000 --print-logs --log-level DEBUG RunAtLoad diff --git a/tests/modules/programs/sketchybar/sketchybar-service-expected.plist b/tests/modules/programs/sketchybar/sketchybar-service-expected.plist index e2e3be34..e620aa76 100644 --- a/tests/modules/programs/sketchybar/sketchybar-service-expected.plist +++ b/tests/modules/programs/sketchybar/sketchybar-service-expected.plist @@ -8,8 +8,12 @@ org.nix-community.home.sketchybar ProcessType Interactive - Program - /nix/store/00000000000000000000000000000000-sketchybar/bin/sketchybar + ProgramArguments + + /bin/sh + -c + /bin/wait4path /nix/store && exec /nix/store/00000000000000000000000000000000-sketchybar/bin/sketchybar + RunAtLoad StandardErrorPath diff --git a/tests/modules/services/borgmatic/darwin/expected-agent.plist b/tests/modules/services/borgmatic/darwin/expected-agent.plist index 24cbe4dd..53436923 100644 --- a/tests/modules/services/borgmatic/darwin/expected-agent.plist +++ b/tests/modules/services/borgmatic/darwin/expected-agent.plist @@ -8,9 +8,9 @@ Background ProgramArguments - @borgmatic@/bin/borgmatic - --stats - --list + /bin/sh + -c + /bin/wait4path /nix/store && exec @borgmatic@/bin/borgmatic --stats --list StandardErrorPath /home/hm-user/Library/Logs/borgmatic/launchd-stderr.log diff --git a/tests/modules/services/colima/darwin/expected-agent.plist b/tests/modules/services/colima/darwin/expected-agent.plist index e4e43477..6a73e56c 100644 --- a/tests/modules/services/colima/darwin/expected-agent.plist +++ b/tests/modules/services/colima/darwin/expected-agent.plist @@ -13,12 +13,9 @@ org.nix-community.home.colima-default ProgramArguments - @colima@/bin/colima - start - default - -f - --activate=true - --save-config=false + /bin/sh + -c + /bin/wait4path /nix/store && exec @colima@/bin/colima start default -f '--activate=true' '--save-config=false' RunAtLoad diff --git a/tests/modules/services/emacs/darwin/expected-agent.plist b/tests/modules/services/emacs/darwin/expected-agent.plist index 81945758..cc9b7682 100644 --- a/tests/modules/services/emacs/darwin/expected-agent.plist +++ b/tests/modules/services/emacs/darwin/expected-agent.plist @@ -13,8 +13,9 @@ org.nix-community.home.emacs ProgramArguments - @emacs@/bin/emacs - --fg-daemon + /bin/sh + -c + /bin/wait4path /nix/store && exec @emacs@/bin/emacs --fg-daemon RunAtLoad diff --git a/tests/modules/services/espanso/darwin/launchd.plist b/tests/modules/services/espanso/darwin/launchd.plist index a38c6f2c..c2b65479 100644 --- a/tests/modules/services/espanso/darwin/launchd.plist +++ b/tests/modules/services/espanso/darwin/launchd.plist @@ -18,8 +18,9 @@ org.nix-community.home.espanso ProgramArguments - @espanso@/Applications/Espanso.app/Contents/MacOS/espanso - launcher + /bin/sh + -c + /bin/wait4path /nix/store && exec @espanso@/Applications/Espanso.app/Contents/MacOS/espanso launcher RunAtLoad diff --git a/tests/modules/services/git-sync/darwin/expected-agent.plist b/tests/modules/services/git-sync/darwin/expected-agent.plist index 2699a996..53d8156e 100644 --- a/tests/modules/services/git-sync/darwin/expected-agent.plist +++ b/tests/modules/services/git-sync/darwin/expected-agent.plist @@ -8,7 +8,9 @@ Background ProgramArguments - @git-sync@/bin/git-sync + /bin/sh + -c + /bin/wait4path /nix/store && exec @git-sync@/bin/git-sync StartInterval 500 diff --git a/tests/modules/services/gpg-agent/expected-agent.plist b/tests/modules/services/gpg-agent/expected-agent.plist index 5843ff44..093e3137 100644 --- a/tests/modules/services/gpg-agent/expected-agent.plist +++ b/tests/modules/services/gpg-agent/expected-agent.plist @@ -20,8 +20,9 @@ Background ProgramArguments - @gpg@/bin/gpg-agent - --supervised + /bin/sh + -c + /bin/wait4path /nix/store && exec @gpg@/bin/gpg-agent --supervised RunAtLoad diff --git a/tests/modules/services/home-manager-auto-expire/darwin/expected-agent.plist b/tests/modules/services/home-manager-auto-expire/darwin/expected-agent.plist index fb3878d1..5d974246 100644 --- a/tests/modules/services/home-manager-auto-expire/darwin/expected-agent.plist +++ b/tests/modules/services/home-manager-auto-expire/darwin/expected-agent.plist @@ -8,7 +8,9 @@ Background ProgramArguments - /nix/store/00000000000000000000000000000000-home-manager-auto-expire + /bin/sh + -c + /bin/wait4path /nix/store && exec /nix/store/00000000000000000000000000000000-home-manager-auto-expire StandardErrorPath /home/hm-user/Library/Logs/home-manager-auto-expire/launchd-stderr.log diff --git a/tests/modules/services/imapnotify/darwin/launchd.plist b/tests/modules/services/imapnotify/darwin/launchd.plist index 75009bb6..4fb9555c 100644 --- a/tests/modules/services/imapnotify/darwin/launchd.plist +++ b/tests/modules/services/imapnotify/darwin/launchd.plist @@ -17,9 +17,9 @@ Background ProgramArguments - @goimapnotify@/bin/goimapnotify - -conf - /nix/store/00000000000000000000000000000000-imapnotify-hm-example.com-config.json + /bin/sh + -c + /bin/wait4path /nix/store && exec @goimapnotify@/bin/goimapnotify -conf /nix/store/00000000000000000000000000000000-imapnotify-hm-example.com-config.json RunAtLoad diff --git a/tests/modules/services/macos-remap-keys/basic-agent.plist b/tests/modules/services/macos-remap-keys/basic-agent.plist index fa3da3cb..f223bf31 100644 --- a/tests/modules/services/macos-remap-keys/basic-agent.plist +++ b/tests/modules/services/macos-remap-keys/basic-agent.plist @@ -11,10 +11,9 @@ org.nix-community.home.remap-keys ProgramArguments - /usr/bin/hidutil - property - --set - { "UserKeyMapping": [ { "HIDKeyboardModifierMappingSrc": 0x700000039, "HIDKeyboardModifierMappingDst": 0x70000002A } ] } + /bin/sh + -c + /bin/wait4path /nix/store && exec /usr/bin/hidutil property --set '{ "UserKeyMapping": [ { "HIDKeyboardModifierMappingSrc": 0x700000039, "HIDKeyboardModifierMappingDst": 0x70000002A } ] }' RunAtLoad diff --git a/tests/modules/services/nix-gc/darwin/expected-agent.plist b/tests/modules/services/nix-gc/darwin/expected-agent.plist index 13b16c16..4691c2e4 100644 --- a/tests/modules/services/nix-gc/darwin/expected-agent.plist +++ b/tests/modules/services/nix-gc/darwin/expected-agent.plist @@ -6,8 +6,9 @@ org.nix-community.home.nix-gc ProgramArguments - @nix@/bin/nix-collect-garbage - --delete-older-than 30d + /bin/sh + -c + /bin/wait4path /nix/store && exec @nix@/bin/nix-collect-garbage '--delete-older-than 30d' StartCalendarInterval diff --git a/tests/modules/services/ollama/darwin/expected-agent.plist b/tests/modules/services/ollama/darwin/expected-agent.plist index 97ed3c8a..daeccc78 100644 --- a/tests/modules/services/ollama/darwin/expected-agent.plist +++ b/tests/modules/services/ollama/darwin/expected-agent.plist @@ -24,8 +24,9 @@ Background ProgramArguments - @ollama@/bin/ollama - serve + /bin/sh + -c + /bin/wait4path /nix/store && exec @ollama@/bin/ollama serve \ No newline at end of file diff --git a/tests/modules/services/podman/darwin/basic-expected-agent.plist b/tests/modules/services/podman/darwin/basic-expected-agent.plist index 146a1827..341a43b3 100644 --- a/tests/modules/services/podman/darwin/basic-expected-agent.plist +++ b/tests/modules/services/podman/darwin/basic-expected-agent.plist @@ -15,7 +15,9 @@ Background ProgramArguments - /nix/store/00000000000000000000000000000000-podman-machine-watchdog-podman-machine-default + /bin/sh + -c + /bin/wait4path /nix/store && exec /nix/store/00000000000000000000000000000000-podman-machine-watchdog-podman-machine-default RunAtLoad diff --git a/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist b/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist index 056846e0..3668a1fc 100644 --- a/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist +++ b/tests/modules/services/podman/darwin/custom-machines-dev-expected-agent.plist @@ -15,7 +15,9 @@ Background ProgramArguments - /nix/store/00000000000000000000000000000000-podman-machine-watchdog-dev-machine + /bin/sh + -c + /bin/wait4path /nix/store && exec /nix/store/00000000000000000000000000000000-podman-machine-watchdog-dev-machine RunAtLoad diff --git a/tests/modules/services/proton-pass-agent/basic-service-expected.plist b/tests/modules/services/proton-pass-agent/basic-service-expected.plist index a4380df5..e8f71a8c 100644 --- a/tests/modules/services/proton-pass-agent/basic-service-expected.plist +++ b/tests/modules/services/proton-pass-agent/basic-service-expected.plist @@ -15,9 +15,9 @@ Background ProgramArguments - @bash-interactive@/bin/bash + /bin/sh -c - @proton-pass-cli@/bin/pass-cli ssh-agent start --socket-path $(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/proton-pass-agent/socket + /bin/wait4path /nix/store && exec @bash-interactive@/bin/bash -c '@proton-pass-cli@/bin/pass-cli ssh-agent start --socket-path $(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/proton-pass-agent/socket' RunAtLoad diff --git a/tests/modules/services/proton-pass-agent/full-service-expected.plist b/tests/modules/services/proton-pass-agent/full-service-expected.plist index 9d0e9690..aa462e83 100644 --- a/tests/modules/services/proton-pass-agent/full-service-expected.plist +++ b/tests/modules/services/proton-pass-agent/full-service-expected.plist @@ -15,9 +15,9 @@ Background ProgramArguments - @bash-interactive@/bin/bash + /bin/sh -c - @proton-pass-cli@/bin/pass-cli ssh-agent start --socket-path $(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/proton-pass-agent/socket --share-id 123456789 --vault-name MySshKeyVault --refresh-interval 7200 --create-new-identities MySshKeyVault + /bin/wait4path /nix/store && exec @bash-interactive@/bin/bash -c '@proton-pass-cli@/bin/pass-cli ssh-agent start --socket-path $(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/proton-pass-agent/socket --share-id 123456789 --vault-name MySshKeyVault --refresh-interval 7200 --create-new-identities MySshKeyVault' RunAtLoad diff --git a/tests/modules/services/ssh-agent/darwin/basic-service-expected.plist b/tests/modules/services/ssh-agent/darwin/basic-service-expected.plist index 1a939f6a..6c8d8d2c 100644 --- a/tests/modules/services/ssh-agent/darwin/basic-service-expected.plist +++ b/tests/modules/services/ssh-agent/darwin/basic-service-expected.plist @@ -15,9 +15,9 @@ Background ProgramArguments - @bash-interactive@/bin/bash + /bin/sh -c - @openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent" + /bin/wait4path /nix/store && exec @bash-interactive@/bin/bash -c '@openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent"' RunAtLoad diff --git a/tests/modules/services/ssh-agent/darwin/pkcs11-service-expected.plist b/tests/modules/services/ssh-agent/darwin/pkcs11-service-expected.plist index d6b5d8fb..72139397 100644 --- a/tests/modules/services/ssh-agent/darwin/pkcs11-service-expected.plist +++ b/tests/modules/services/ssh-agent/darwin/pkcs11-service-expected.plist @@ -15,9 +15,9 @@ Background ProgramArguments - @bash-interactive@/bin/bash + /bin/sh -c - @openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent" -P '/usr/lib/libpkcs11.so,/usr/lib/other.so' + /bin/wait4path /nix/store && exec @bash-interactive@/bin/bash -c '@openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent" -P '\''/usr/lib/libpkcs11.so,/usr/lib/other.so'\''' RunAtLoad diff --git a/tests/modules/services/ssh-agent/darwin/timeout-service-expected.plist b/tests/modules/services/ssh-agent/darwin/timeout-service-expected.plist index 0a49f024..6facee27 100644 --- a/tests/modules/services/ssh-agent/darwin/timeout-service-expected.plist +++ b/tests/modules/services/ssh-agent/darwin/timeout-service-expected.plist @@ -15,9 +15,9 @@ Background ProgramArguments - @bash-interactive@/bin/bash + /bin/sh -c - @openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent" -t 1337 + /bin/wait4path /nix/store && exec @bash-interactive@/bin/bash -c '@openssh@/bin/ssh-agent -D -a "$(@getconf-system_cmds@/bin/getconf DARWIN_USER_TEMP_DIR)/ssh-agent" -t 1337' RunAtLoad diff --git a/tests/modules/services/syncthing/expected-agent.plist b/tests/modules/services/syncthing/expected-agent.plist index 72ec9d0d..72cf9870 100644 --- a/tests/modules/services/syncthing/expected-agent.plist +++ b/tests/modules/services/syncthing/expected-agent.plist @@ -15,7 +15,9 @@ Background ProgramArguments - @syncthing-wrapper@ + /bin/sh + -c + /bin/wait4path /nix/store && exec @syncthing-wrapper@ \ No newline at end of file diff --git a/tests/modules/services/yubikey-agent/darwin/service.nix b/tests/modules/services/yubikey-agent/darwin/service.nix index 8d707450..c8bd674f 100644 --- a/tests/modules/services/yubikey-agent/darwin/service.nix +++ b/tests/modules/services/yubikey-agent/darwin/service.nix @@ -27,9 +27,9 @@ Background ProgramArguments - @yubikey-agent@/bin/yubikey-agent - -l - /tmp/yubikey-agent.sock + /bin/sh + -c + /bin/wait4path /nix/store && exec @yubikey-agent@/bin/yubikey-agent -l /tmp/yubikey-agent.sock Sockets