Differences between `nix build` and development shell

I have a flake for providing the dependencies for a Rust project. All the tests pass in the direnv-enabled development environment, but there are failures in nix build. The problem seems to be related to the cfg seen by rustc.

What tools/strategies are there for poking around in the nix build environment?

Manual invocation of nix shell reproduces the same error (with the same nix log hash), but, because it fails, it still doesn’t give me interactive access to the environment.

Debugging always starts with reading the error.

More often than not it requires a bit of understanding of nix, the original buildsystem and it’s specialties within nix.

Also there are the differences because of the sandbox.

I’m not aware of a way to actually “enter” the sandbox

Which can be easier said than done … for example when, after 45 minutes of CI churning you get confronted with

error: builder for '/nix/store/<SHA>-whatever.drv' failed with exit code 1;
       last 10 log lines:
       For full logs, run 'nix log /nix/store/<SHA>-whatever.drv'.

leaving you with no way to actually run that nix log /nix/store/<SHA>-whatever.drv.

This can be a tad soul-crushing, if it occurs 12 levels of error removed from your original goal.

And then …

… having no interactive way of investigating the possible causes of the error you’re seeing, is a huge impediment to progress.

This problem arose in a project which uses cargo2nix. I’m trying to reduce it to a minimal example, and now grind to a halt with this (in response to nix build and direnv-use flake, when trying to remove a cargo workspace member):

@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/yc3aqsbqd8nvd4wwanz2kz69bsd5y7hw-4p2g67jn21xvhd2nlr6safz5m9ag623w-source
source root is 4p2g67jn21xvhd2nlr6safz5m9ag623w-source
@nix { "action": "setPhase", "phase": "buildPhase" }
++ crate2nix generate -f ./Cargo.toml -o Cargo-generated.nix -h /nix/store/pk0fm1h2cpimq92y6rvnaj9l97hn58xj-petalo-crate2nix/crate-hashes.json
Error: while retrieving metadata about ./Cargo.toml: `cargo metadata` exited with an error: error: the lock file /build/4p2g67jn21xvhd2nlr6safz5m9ag623w-source/Cargo.lock needs to be updated but --locked was passed to prevent this
If you want to try to generate the lock file without accessing the network, remove the --locked flag and use --offline instead.
crate2nix failed.

That --locked flag I am advised to remove comes from somewhere buried under layers of magic, so I have no idea how to proceed. I’m confronted with this sort of error every few months. I have no recollection of how I got around it in the past. I vaguely associate it with forgetting to git add stuff in new flakes, but that’s a very hazy memory and I’m probably misremembering.

  1. Why don’t you build locally?
  2. Have you considered using -L for full log?
1 Like

I’m managing to hack around the problem like this:

  1. nix run nixpkgs#cargo metadata
  2. touch flake.nix

The problem first appeared on CI, because locally direnv invokes nix automatically with an environment isn’t identical to the sandbox. Now that I know I can reproduce the problem locally with nix build, I am.

Didn’t know about that one. Thanks!

Is there a way to get direnv to use -L?

No, as direnv uses print-dev-env under the hood, and if that would stream additional logs to stout, it would break the expectations that there is nothing but the evalable shell script printed

To cut a long story short, completely removing Cargo.lock and flake.lock (though I suspect it was the former that mattered) from the repository and regenerating them from scratch, seems to have solved that particular problem … though I’m now stuck on the next perplexing and seemingly unrelated error.

These cascades of weird errors with no time to get to understand what was really going with any of them, are really depressing.