Skip to content

docs(contributing): document how to debug Devbox locally - #2893

Closed
mikeland73 wants to merge 2 commits into
mainfrom
claude/focused-goldberg-6nhmso
Closed

mikeland73 wants to merge 2 commits into
mainfrom
claude/focused-goldberg-6nhmso

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Resolves #2699.

Several Devbox commands (e.g. devbox shell, devbox services up) do little work themselves — they re-exec a nested devbox subprocess inside the project's shell environment, and that subprocess does the real work. The nested process is resolved from PATH, so it's usually the installed version of Devbox rather than the local build you're editing. This is why devbox run build && dist/devbox services up may silently run old code, and why DEVBOX_DEBUG=1 logs / breakpoints added to a local build don't fire.

The issue author hit exactly this and asked for it to be documented in the repo. This PR adds a "Debugging Devbox Locally" section to CONTRIBUTING.md describing the two workarounds they found:

  1. Point the launcher at your local build via DEVBOX_USE_VERSION (most faithful — every invocation, including nested subprocesses, uses your build).
  2. The hidden --run-in-current-shell flag (quick to iterate, but bypasses the nested re-exec so behavior differs slightly).

Verification

The documented behavior was confirmed against the code:

  • devbox run builddist/devbox (devbox.json).
  • devbox services … re-execs a nested devbox subprocess unless --run-in-current-shell is set (internal/devbox/services.gorunDevboxServicesScript runs the devbox on PATH inside the shell; the flag is registered hidden in internal/boxcli/services.go).
  • DEVBOX_USE_VERSION is the version-override env the launcher honors and that Devbox preserves across re-launches (internal/setup/setup.go, internal/devbox/providers/nixcache/setup.go).

Docs-only change; no code paths affected.

cc @jay-aye-see-kay (issue author) — thanks for the detailed write-up of the workaround.

🤖 Generated with Claude Code

https://claude.ai/code/session_014fiBLNEAEGUcCJPZ1qpGp6


Generated by Claude Code

Many commands (e.g. `devbox shell`, `devbox services up`) re-exec a nested
`devbox` subprocess that does the real work. That subprocess is resolved from
PATH, so it is typically the installed Devbox rather than your local build,
which is why debug logs/breakpoints added to a local build don't fire.

Add a "Debugging Devbox Locally" section to CONTRIBUTING.md describing the two
workarounds: pointing the launcher at a local build via DEVBOX_USE_VERSION
(most faithful), and the hidden `--run-in-current-shell` flag (quick).

Fixes #2699

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

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

Adds contributor documentation explaining why some Devbox commands don’t execute the locally-built binary (due to nested devbox re-exec from PATH) and how to reliably debug local changes.

Changes:

  • Document the nested devbox subprocess behavior that can cause local builds/logs/breakpoints to be ignored.
  • Add two debugging workarounds: DEVBOX_USE_VERSION (launcher override) and --run-in-current-shell (skip re-exec).

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

Comment thread CONTRIBUTING.md
Comment thread CONTRIBUTING.md Outdated
The launcher's binary cache lives under XDG_CACHE_HOME (falling back to
~/.cache), so use ${XDG_CACHE_HOME:-$HOME/.cache} instead of hard-coding
$HOME/.cache. Factor the path into a variable to avoid repetition.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fiBLNEAEGUcCJPZ1qpGp6
@mikeland73

Copy link
Copy Markdown
Collaborator Author

@claude please review this PR for correctness, and flag anything that would block merging.

@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown

Claude finished @mikeland73's task in 3m 21s —— View job


Review of PR #2893

  • Gather context (diff, file, prior review comments)
  • Verify claims about nested re-exec / launcher behavior against source
  • Check XDG fix from commit 1395772 is applied correctly
  • Post review findings

What checks out:

  • devbox run builddist/devbox — confirmed via devbox.json's scripts.build.
  • devbox services {up,start,stop,restart,ls} genuinely re-exec into a nested devbox subprocess resolved from PATH — confirmed in internal/devbox/services.go:272-275 (runDevboxServicesScriptd.RunScript(..., "devbox", cmdArgs)), unless --run-in-current-shell is passed.
  • The XDG fix in 1395772 (cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/...", CONTRIBUTING.md:85) is correctly applied and addresses the earlier review comment.
  • DEVBOX_USE_VERSION is preserved across Devbox's own internal re-execs (internal/setup/setup.go:183, internal/devbox/providers/nixcache/setup.go:202), consistent with the doc's claim that it propagates to nested invocations.

Correctness concerns (worth fixing before merge):

  1. devbox shell is a weak/inaccurate motivating example (CONTRIBUTING.md:66-75). The doc opens by citing devbox shell alongside devbox services up as a command that "does little work itself" and re-execs a nested subprocess that "does the real work." That's not what the code shows: Shell() (internal/devbox/devbox.go:227-261) does the real work (computing env, building the nix shell) in-process. The only nested devbox invocations spawned inside the resulting shell are devbox log shell-ready / devbox log shell-interactive in internal/devbox/shellrc.tmpl — lightweight telemetry calls, not "the real work" that would cause DEVBOX_DEBUG logs or breakpoints to silently not fire. The re-exec-masks-your-build problem is real for devbox services * (and similarly for anything invoked via devbox run), but devbox shell doesn't clearly suffer from it the way it's framed here.

  2. Workaround Allow overwrites on install, build and start command #2 doesn't apply to the doc's own first example. --run-in-current-shell is registered as a PersistentFlags() only on servicesCommand (internal/boxcli/services.go:138-144), scoped to devbox services * subcommands. It does not exist for devbox shell. So "Many commands accept a hidden --run-in-current-shell flag" (CONTRIBUTING.md:94) overstates its scope, and a reader who hit the devbox shell case from the intro has no way to apply workaround Allow overwrites on install, build and start command #2 to it.

    Suggested fix: either drop devbox shell from the opening example (keep it focused on devbox services/devbox run-style commands, where the claim is fully accurate), or add a caveat that --run-in-current-shell is devbox services-only.

  3. Minor / unverifiable in this session: the exact binary cache path ($XDG_CACHE_HOME/devbox/bin/<version>_<os>_<arch>/devbox) is determined by the external launch.sh launcher script, which isn't part of this repo (only referenced as "keep in sync with launch.sh" in internal/vercheck/vercheck.go:29). I didn't have network access in this session to fetch and confirm that script matches the documented path format. Worth double-checking workaround Add quickstart to Readme #1 was tested end-to-end (build → copy to cache dir → DEVBOX_USE_VERSION → confirm the launcher actually picks it up) before merging, since a mismatched path would make the primary workaround silently a no-op.

Nothing here is a functional/build risk since this is docs-only, but #1 and #2 are factual inaccuracies in a doc whose whole purpose is precise debugging instructions, so I'd flag them as blocking for a docs PR.

Fix this →

@mikeland73 mikeland73 added the ready for human review Automated review passed; needs a maintainer to review and merge label Sep 14, 2026
@mikeland73

Copy link
Copy Markdown
Collaborator Author

Closing: the root cause was fixed in #2936devbox services … now re-execs the currently running binary via os.Executable() instead of resolving devbox from PATH, so devbox run build && dist/devbox <cmd> picks up local changes end to end and the workarounds documented here are no longer needed.

@mikeland73 mikeland73 closed this Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for human review Automated review passed; needs a maintainer to review and merge

Development

Successfully merging this pull request may close these issues.

nested shells make it harder to debug issues; document workarounds for better local dev

3 participants