nix-community/nix-direnv

Loading envrc fails due to minimum required nix-direnv version

sagikazarmark opened this issue · 10 comments

I have the following in my .envrc:

if ! has nix_direnv_version || ! nix_direnv_version 3.0.2; then
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.2/direnvrc" "sha256-i/Kz3NhCql8UNBtJMJDVxMH1PYvxzu+S5wjg63fQGas="
fi
use flake . --impure

When changing into the directory, I get:

direnv: loading ~/Projects/.../.envrc
direnv: nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)
direnv: error exit status 1

I indeed have nix-direnv 3.0.1 installed in my environment (using home-manager), but prior to 3.0.0, that wasn't an issue. nix_direnv_version correctly detected the version mismatch and installed the proper nix-direnv version.

Going back to pre-3.0.0 resolves the problem.

Don't know if it matters, but I use ZSH.

Mic92 commented

direnv: nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1) is only a warning. The error is likely in the line after use flake . --impure, you can verify by commenting it out.

Thanks @Mic92!

Removing/commenting those lines out results in the same error.

Tried it on a fresh clone as well, same results.

Is there a way I can debug the issue further/provide more information?

Mic92 commented

you can add set -x to see on which command it fails.

Is the .envrc snippet you posted above the entirety of your .envrc? If not - can you post the entirety?

You can add set -x anywhere in the .envrc to debug what's happening, as noted by @Mic92 above. You can additionally add echos to see what values things have before the use flake call. Notably this is helpful in debugging which direnv (with echo $direnv) and which nix-direnv version you have invoked (with echo $NIX_DIRENV_VERSION, but we already know you're somehow invoking 3.0.1).

What is the content of your user's direnv configuration file? Is there something that's possibly going wrong in there?

set -x is probably the best bet to getting a meaningful output though.

Is the .envrc snippet you posted above the entirety of your .envrc? If not - can you post the entirety?

Yes, it is. (Although I added a dotenv entry since after use flake)

What is the content of your user's direnv configuration file? Is there something that's possibly going wrong in there?

❯ cat ~/.config/direnv/direnvrc
source /nix/store/apqrlibx40s40mixpky575rscvmynjzm-nix-direnv-3.0.1/share/nix-direnv/direnvrc

(I installed direnv with nix-direnv using Home Manager)

After adding set -x

set -x

echo $NIX_DIRENV_VERSION

if ! has nix_direnv_version || ! nix_direnv_version 3.0.2; then
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.2/direnvrc" "sha256-i/Kz3NhCql8UNBtJMJDVxMH1PYvxzu+S5wjg63fQGas="
fi

echo $NIX_DIRENV_VERSION

use flake . --impure

dotenv_if_exists .env.local

Result:

++ echo 3.0.1
3.0.1
++ has nix_direnv_version
++ type nix_direnv_version
++ nix_direnv_version 3.0.2
++ _require_version nix-direnv 3.0.1 3.0.2
++ local cmd=nix-direnv version=3.0.1 required=3.0.2
++ printf '%s\n' 3.0.2 3.0.1
++ sort --check=quiet --version-sort
++ _nix_direnv_fatal 'minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)'
++ log_error 'nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)'
++ [[ -n direnv: %s ]]
++ local 'msg=nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)' color_normal= color_error=
++ [[ -t 2 ]]
++ color_normal='\e[m'
++ color_error='\e[38;5;1m'
++ printf '\e[38;5;1mdirenv: %s\e[m\n' 'nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)'
direnv: nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1)
++ exit 1
+ __dump_at_exit
+ local ret=1
+ /nix/store/iw865954x7mx57ybc8zyghspisvmfzs7-direnv-2.33.0/bin/direnv dump json ''
+ trap - EXIT
+ exit 1
direnv: error exit status 1

It doesn't get to the second echo

direnv: nix-direnv: minimum required nix-direnv version is 3.0.2 (installed: 3.0.1) is only a warning. The error is likely in the line after use flake . --impure, you can verify by commenting it out.

This is not true. nix_direnv_version calls _nix_direnv_fatal, which fails immediately after logging with exit 1. The exit 1 then propagates outward. This was changed in 26d7044 ("refactor logging" by @kingarrrt) and points to a difference between return and exit with regard to strict mode. I think we should revert to using return here because the user is expecting ! nix_direnv_version 3.0.2 to not immediately exit, but rather allow continual processing. I think this was a misunderstanding on @kingarrrt's part during the rewrite?

@sagikazarmark This is a genuine change in behavior. Sorry to effectively gaslight you for a bit there. We'll get it sorted. Until then, you might want to just unconditionally call source_url in your project, as it'll at least get you a consistent version of nix-direnv

Mic92 commented

Fixed in #457

@bbenne10 no worries, I appreciate the help and the quick reactions. Also, thanks @Mic92 for the prompt fix.