fix(add): fail fast with a clear error when a package isn't found - #2996
mikeland73 wants to merge 2 commits into
Conversation
When the search service doesn't know a bare package name (e.g. `devbox add inotifywait`), return an error that suggests `devbox search` instead of downloading nixpkgs and running `nix search`, which is slow and often fails with a confusing error. Dotted attribute paths (stdenv.cc.cc.lib, openssl.dev, python3Packages.requests) aren't all indexed by search, so those still fall back to nixpkgs. Also stop the v1 resolver from reporting network and server errors as "package not found". Fixes #2765 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@claude ptal |
|
Claude finished @mikeland73's task in 23s —— View job Review of #2996The change is small and targeted, and the approach looks sound. I read the diff and the surrounding code. I did not build it or run the tests. I found one real issue and a few nits. Issue: flake and non-devbox packages hit the new branch with an empty hint
Suggested fix: gate the new branch on } else if errors.Is(err, nix.ErrPackageNotFound) &&
pkg.IsDevboxPackage &&
!strings.Contains(pkg.CanonicalName(), ".") {Non-devbox packages then keep their existing behavior. If you'd rather keep the new message for them, Nits
|
- Gate the not-found fast path on IsDevboxPackage so flake refs and other non-devbox packages keep propagating their original error instead of getting an empty `devbox search` hint. - Note in the comment that the fast path is a heuristic. - Add a unit test that /v1/resolve and /v2/resolve map only 404s to ErrPackageNotFound. - Add a testscript for `devbox add` with a missing package. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Summary
Fixes #2765.
devbox add inotifywait(a binary ininotify-tools, not a package) downloaded nixpkgs and rannix search, then failed with a confusing error:Now it fails in about 0.4s without touching nixpkgs:
., return the error immediately. In a random sample of 150 of nixpkgs' ~24.8k top-level derivations, all 150 resolved in search, so the nixpkgs fallback wouldn't find these either.python3Packages.requests,beamPackages.hex), outputs (openssl.dev,gcc-unwrapped.lib) orstdenv.cc.cc.lib, and those work onmainthrough the fallback. If the fallback also fails, the user gets the same message.FetchResolvedPackagereported every/v1/resolveerror asErrPackageNotFound, including network and server errors. It now does that only for a 404. The v2 resolver (the default) already behaved this way.Test plan
Manual, with a locally built binary:
inotifywaitdevbox searchhintnodejs@99999devbox search nodejsstdenv.cc.cc.libmain)openssl.devmain)python3Packages.requestsmain)foo.barbazhellohello@latestTestFetchResolvedPackageErrors: with both v1 and v2 resolvers, a 404 maps toErrPackageNotFoundand a 500 does not. It fails onmain's v1 resolver.testscripts/add/add_not_found.test.txt:devbox add inotifywaitanddevbox add hello@99999fail with the new message and don't download nixpkgs.go test ./testscripts/ -run TestScripts/add, alladd*testscripts pass, includingadd.test.txt, which covers thestdenv.cc.cc.libfallbackgo test ./internal/devbox/... ./internal/lock/... ./internal/boxcli/...golangci-lint run ./internal/devbox/... ./internal/lock/...: 0 issues🤖 Generated with Claude Code