A flake input is evaluated from its source directory rather than its store copy, so any import ./x.nix inside an input's flake.nix is an absolute out-of-store path and pure evaluation rejects it.
$ mkdir -p /tmp/dep /tmp/root
$ printf '{ hello = "world"; }\n' > /tmp/dep/lib.nix
$ printf '{\n outputs = _: { lib = import ./lib.nix; };\n}\n' > /tmp/dep/flake.nix
$ printf '{\n inputs.dep.url = "path:/tmp/dep";\n outputs = { dep, ... }: { value = dep.lib.hello; };\n}\n' > /tmp/root/flake.nix
$ cd /tmp/root
$ nix eval .#value
"world"
$ fix eval --extra-experimental-features flakes --flake '.#value'
error: access to absolute path '/tmp/dep/lib.nix' is forbidden in pure evaluation mode (use --impure to allow)
trace:
note: while evaluating 'outputs.lib' at /tmp/dep/flake.nix:2:24
2 | outputs = _: { lib = import ./lib.nix; };
| ^^^^^^^^^^^^^^^^
$ fix eval --extra-experimental-features flakes --impure --flake '.#value'
"world"
Nix copies each input to the store and evaluates its flake.nix from there, so ./lib.nix resolves under /nix/store/…-source and is allowed in pure mode. fix evaluates the input in place, so the same import is a plain absolute path and the pure-eval check fires.
The store copy is not missing, only unused by evaluation. A tarball input shows both halves in one run — the fetch is stored, and the eval still reads the cache directory:
$ fix build --flake '.#' --extra-experimental-features flakes # a flake-parts flake
[ 115ms] [fetch] cached https://codeload.github.com/hercules-ci/flake-parts/tar.gz/17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e
[ 124ms] [daemon] stored /nix/store/xfg4bws749i95jvnxhymxmfwailzk38q-source
…
error: input 1 derivation selection failed: RestrictedInPureEval
$ fix eval --extra-experimental-features flakes --flake '.#packages.aarch64-darwin.default'
error: access to absolute path '/Users/…/.cache/fix/tarball/15646a24e94e42e737ce3a363972a4d7/source/lib.nix' is forbidden in pure evaluation mode (use --impure to allow)
trace:
note: while evaluating 'outputs.lib' at /Users/…/.cache/fix/tarball/15646a24e94e42e737ce3a363972a4d7/source/flake.nix:10:13
10 | lib = import ./lib.nix {
| ^^^^^^^^^^^^^^^^^^
Splitting a flake across a couple of files is ordinary — flake-parts does it, so every flake built on flake-parts hits this — and a --flake installable is pure by default, so eval, build and instantiate all fail on such a flake unless --impure is passed, which is a poor trade for a CI check.
Two smaller things fall out of the same run. build reports the restriction as error: input 1 derivation selection failed: RestrictedInPureEval with no path, no trace and no mention of --impure, so the cause is only visible by re-running under eval. And fix flake check evaluates the same flake-parts flake to checked 14 flake output(s): ok, so it is not applying the pure-eval restriction that --flake installables apply.
fix 0.3.0, release binary fix-v0.3.0-aarch64-darwin.tar.gz, darwin/aarch64. Reference implementation is Nix 2.34.8.
A flake input is evaluated from its source directory rather than its store copy, so any
import ./x.nixinside an input'sflake.nixis an absolute out-of-store path and pure evaluation rejects it.Nix copies each input to the store and evaluates its
flake.nixfrom there, so./lib.nixresolves under/nix/store/…-sourceand is allowed in pure mode.fixevaluates the input in place, so the same import is a plain absolute path and the pure-eval check fires.The store copy is not missing, only unused by evaluation. A tarball input shows both halves in one run — the fetch is stored, and the eval still reads the cache directory:
Splitting a flake across a couple of files is ordinary — flake-parts does it, so every flake built on flake-parts hits this — and a
--flakeinstallable is pure by default, soeval,buildandinstantiateall fail on such a flake unless--impureis passed, which is a poor trade for a CI check.Two smaller things fall out of the same run.
buildreports the restriction aserror: input 1 derivation selection failed: RestrictedInPureEvalwith no path, no trace and no mention of--impure, so the cause is only visible by re-running undereval. Andfix flake checkevaluates the same flake-parts flake tochecked 14 flake output(s): ok, so it is not applying the pure-eval restriction that--flakeinstallables apply.fix 0.3.0, release binary
fix-v0.3.0-aarch64-darwin.tar.gz, darwin/aarch64. Reference implementation is Nix 2.34.8.