Skip to content

fix(nix): detect nix at known locations, not just $PATH (#2787)#2903

Open
mikeland73 wants to merge 1 commit into
mainfrom
claude/focused-goldberg-i7mw9s
Open

fix(nix): detect nix at known locations, not just $PATH (#2787)#2903
mikeland73 wants to merge 1 commit into
mainfrom
claude/focused-goldberg-i7mw9s

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2787.

Users on setups where nix is installed but not on the interactive shell's $PATH — notably NixOS, and shells that don't source the Nix profile the way devbox expects (e.g. fish) — hit this even though nix is present and working:

Error: We found a /nix directory but nix binary is not in your PATH and we were not able to find it in the usual locations. Your nix installation might be broken.

The root cause is that devbox used two different mechanisms to find nix:

  • To run nix commands, nix.(*Nix).resolvePath() searches $PATH and then falls back to well-known install locations, invoking nix by absolute path. This works even when nix isn't on $PATH.
  • To detect whether nix is installed, BinaryInstalled() used a bare exec.LookPath("nix") — a $PATH-only check.

So detection could report nix as missing and abort in EnsureNixInstalled, even though devbox would have been perfectly able to run nix by absolute path.

On top of that, resolvePath's fallback list had a latent bug: the NixOS entry was the bin directory /run/current-system/sw/bin, but the loop only accepts a path that is a non-directory executable — so that entry could never match, and the NixOS system-profile location was effectively never searched.

Fix

  • internal/nix/install.go: BinaryInstalled() now uses the same resolver that runs nix commands, via a new exported nix.(*Nix).LookPath / nix.LookPath. Detection and execution can no longer disagree.
  • nix/nix.go: fix the fallback list so the NixOS entry points at the nix binary (/run/current-system/sw/bin/nix), and extract the list into nixBinaryFallbackPaths().
  • The happy path is unchanged: nix on $PATH is still found first; behavior only differs when nix is off-$PATH but present at a known location, where devbox now proceeds instead of erroring.

How was it tested?

  • go build ./nix/... ./internal/nix/... ./internal/boxcli/... passes.
  • go test ./nix/... passes, including a new TestNixBinaryFallbackPaths regression test asserting every fallback entry is an absolute path to the nix binary (guarding against the directory-vs-binary bug) and that the NixOS system-profile path is covered.
  • go test ./internal/nix/...: the added/affected tests pass. (TestConfigIsUserTrusted fails in this sandbox only because it shells out to a real nix, which isn't installed here — it fails identically on the unchanged base branch and is unrelated to this change.)

cc @simulatedcode (issue reporter)

Community Contribution License

All community contributions in this pull request are licensed to the project
maintainers under the terms of the
Apache 2 License.

By creating this pull request, I represent that I have the right to license the
contributions to the project maintainers under the Apache 2 License as stated in
the
Community Contribution License.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BXJuDH6keqvU1ydywuyizq


Generated by Claude Code

Devbox ran nix commands via resolvePath(), which searches $PATH and then
falls back to well-known install locations, invoking nix by absolute path.
But installation detection (BinaryInstalled) used a bare `exec.LookPath("nix")`
$PATH check. The two disagreed: on NixOS, or when a non-POSIX login shell such
as fish hasn't sourced the Nix profile, nix exists at a known location but
isn't on $PATH, so devbox aborted with "nix binary is not in your PATH" even
though it could have run nix fine.

- Point BinaryInstalled at the same resolver used to run nix commands, via a
  new exported nix.(*Nix).LookPath / nix.LookPath.
- Fix resolvePath's fallback list: the NixOS entry was the bin *directory*
  (/run/current-system/sw/bin), which the "not a directory" check always
  rejected, so it never matched. It now points at the nix binary itself.
- Extract the fallback paths into nixBinaryFallbackPaths() and add a regression
  test asserting each entry is an absolute path to the nix binary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJuDH6keqvU1ydywuyizq
Copilot AI review requested due to automatic review settings July 5, 2026 14:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Nix installation detection so Devbox can proceed when nix exists at well-known locations but is not on the interactive shell’s $PATH (notably on NixOS and in shells like fish), aligning “detection” with the same resolution logic used to actually execute nix.

Changes:

  • Added an exported (*nix.Nix).LookPath method (and nix.LookPath helper) so callers can resolve the nix executable using the same logic as command execution.
  • Fixed and extracted the fallback search list so the NixOS entry points to the nix binary (/run/current-system/sw/bin/nix) rather than the directory.
  • Updated internal/nix.BinaryInstalled to use the resolver (not PATH-only checks) and added a regression test to ensure fallback entries are absolute paths to the nix binary.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
nix/nix.go Exposes LookPath, fixes fallback search behavior, and centralizes fallback paths.
nix/nix_test.go Adds regression test ensuring fallback paths are valid absolute .../nix entries and include the NixOS location.
internal/nix/install.go Updates BinaryInstalled() to rely on the shared resolver to avoid false negatives when nix isn’t on $PATH.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

fish shell: nix unknown.

3 participants