Skip to content

fix(shim): error when secondary executable is missing#255

Merged
CalvinAllen merged 2 commits intomainfrom
fix/shim/silent-fallback-on-missing-executable
May 8, 2026
Merged

fix(shim): error when secondary executable is missing#255
CalvinAllen merged 2 commits intomainfrom
fix/shim/silent-fallback-on-missing-executable

Conversation

@CalvinAllen
Copy link
Copy Markdown
Contributor

Summary

  • When a secondary-executable shim (e.g. uv, pip, npm) cannot be located in the active runtime version's install tree, the shim previously fell back to the primary runtime binary — silently turning uv --version into python --version.
  • Extract the lookup into a shared shim.FindSecondaryExecutable helper that returns an explicit error, and have both the shim entrypoint and dtvem which surface a clear "not available in " message instead of falling back.
  • This also de-duplicates the previously-identical adjustExecutablePath functions in src/cmd/shim/main.go and src/cmd/which.go.

Resolves #254

Behavior change (verified locally)

Before:

$ DTVEM_VERBOSE=1 ~/.dtvem/shims/uv.exe --version
Shim invoked: uv
Mapped to runtime: python
Resolved version: 3.8.9
Base executable path: ...\python\3.8.9\python.exe
Final executable path: ...\python\3.8.9\python.exe
Python 3.8.9

After:

$ DTVEM_VERBOSE=1 ~/.dtvem/shims/uv.exe --version
Shim invoked: uv
Mapped to runtime: python
Resolved version: 3.8.9
Base executable path: ...\python\3.8.9\python.exe
Secondary executable lookup failed: secondary executable not found: uv
✗ 'uv' is not available in Python 3.8.9
→ This shim exists because another installed Python version provides it.
→ Install 'uv' for the active version, or switch to a version that has it.
dtvem shim error: uv not available in Python 3.8.9

Test plan

  • ./rnr check (format, lint, full test suite) passes
  • New unit tests in src/internal/shim/executable_test.go cover: found alongside runtime, found in Scripts/, found in ../Scripts/, .cmd preferred over .exe, not-found returns ErrSecondaryExecutableNotFound
  • End-to-end: rebuilt shim, renamed to uv.exe, ran against a Python version that does not have uv — confirmed clear error
  • End-to-end: rebuilt shim, renamed to python.exe — confirmed primary-runtime path still works
  • CI passes on Windows / macOS / Linux

Note on related work

This does not fix #253 (shim-map cross-version contamination) — that's a separate change. However, fixing this silent-fallback bug significantly mitigates the user-facing impact of #253: users now see a clear error rather than the runtime binary running in place of the missing command.

@CalvinAllen CalvinAllen changed the title fix(shim): error when secondary executable is missing instead of silently running runtime fix(shim): error when secondary executable is missing May 8, 2026
When a secondary executable shim (e.g. uv, pip, npm) cannot be located in
the active runtime version's install tree, the shim previously fell back
to the primary runtime binary, silently turning `uv --version` into
`python --version`.

Extract the lookup into a shared `shim.FindSecondaryExecutable` helper
that returns an explicit error, and have both the shim entrypoint and
`dtvem which` surface a clear "not available in <runtime> <version>"
message instead of falling back.
The `goconst` linter flagged ".bat" as a repeated string literal across
manager.go, manager_test.go, and path.go. Add `constants.ExtBat`
alongside the existing ExtExe / ExtCmd constants and replace the bare
literals (and the bare ".exe"/".cmd" alongside them in the same files)
with the named constants.
@CalvinAllen CalvinAllen force-pushed the fix/shim/silent-fallback-on-missing-executable branch from 6ee2fbb to 50769f6 Compare May 8, 2026 17:19
@CalvinAllen CalvinAllen merged commit 0c49aaa into main May 8, 2026
12 checks passed
@CalvinAllen CalvinAllen deleted the fix/shim/silent-fallback-on-missing-executable branch May 8, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant