nix run commands stuck on post-build step
I am using MacOS Sequoia 15.3.1 (24D70) Nix 2.25.3 installed with determinate systems nix-darwin
When trying to run a nix run command it will get stuck in the post-build step.
I first encountered it in the following command
nix --extra-experimental-features nix-command --extra-experimental-features flakes run nix-darwin/master#darwin-rebuild -- switch --flake ~/.config/nix-darwin/#<flake>
Resulting in
❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
warning: 'https://cache.flakehub.com' does not appear to be a binary cache
[1/0/1 built, 0.0 MiB DL] post-build darwin-system-25.05.a674621
Then I thought something was wrong with my nix-darwin install so I tried uninstalling that with
❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
And that resulted in
❯ nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
warning: 'https://cache.flakehub.com' does not appear to be a binary cache
[5/0/13 built, 0.0 MiB DL] post-build fonts
I first added an issue to the nix-darwin repo https://github.com/LnL7/nix-darwin/issues/1370#issue-2898488787
I have seen this before as well and done the local darwin-uninstaller then uninstalled nix, and then reinstalled both, and it has usually worked for some time. It was now quite some time since I had run and update on my nix-darwin config, and then I suddenly started hanging again.
Do you have any idea of what could cause me ending up in this state?
This identified and resolved the problem for me. I am guessing this is because systems.determinate.nix-daemon is expected to read from that (presumably) FIFO at /nix/var/determinate/intake.pipe mentioned at the bottom of /nix/var/determinate/post-build-hook.sh.
Probably the post-build hook should have some handling here that detects if the FIFO is unwritable or times out and prints some other message.
I haven't tried it but, for inspiration, chatgpt suggests something like this may work:
#!/bin/sh
set -f
export IFS=' '
i=0
# Create a temporary file for the output
temp_file=$(mktemp)
# Prepare the output
{
for p in $OUT_PATHS
do
printf '{"s": %d, "v":"1","c":"add-output","drv":"%s","idx":%d,"output":"%s"}\n' "$$" "$DRV_PATH" $i "$p"
i=$((i + 1))
done
printf '{"s": %d, "v":"1","c":"finish","drv":"%s","count":%d}\n' "$$" "$DRV_PATH" $i
} > "$temp_file"
# Try to write to the FIFO with a timeout using background process
(cat "$temp_file" >> /nix/var/determinate/intake.pipe) &
pid=$!
# Wait for up to 10 seconds
wait_time=0
while [ $wait_time -lt 10 ] && kill -0 $pid 2>/dev/null; do
sleep 1
wait_time=$((wait_time + 1))
done
# Check if the process is still running (blocked)
if kill -0 $pid 2>/dev/null; then
kill $pid
echo "ERROR: Failed to write to FIFO /nix/var/determinate/intake.pipe (timeout)" >&2
rm -f "$temp_file"
exit 1
fi
# Check if the process exited successfully
wait $pid
exit_code=$?
rm -f "$temp_file"
if [ $exit_code -ne 0 ]; then
echo "ERROR: Failed to write to FIFO /nix/var/determinate/intake.pipe (exit code $exit_code)" >&2
exit 1
fi
exit 0