[BUG]: `vfox env` serves the cached output after a `cd`: a .nvmrc / .node-version is ignored on the way in and kept on the way out

Aperta
#745 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
bash, go, nodejs
Ambito
cli

Direzione di ricerca

Start in envFlag in cmd/commands/env.go, where the cache check happens after loadToolChain in cmd/commands/tool_resolution.go has resolved the legacy file. Then read ConfigState.HasChanged in internal/env/state.go to see which inputs it compares. Choosing between the working-directory and resolved-tool-set options is a design call for maintainers. Done when cd between a .nvmrc directory and a plain directory switches node -v at once, and a test covers that transition.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug help wanted

Version
vfox 1.0.13 (release binary) and main at cdf0747 (2026-11-02, RuntimeVersion is still 1.0.13), with the nodejs plugin 0.5.3 from the registry. The two builds print the same lines in everything below.

OS
Linux (Ubuntu 26.04.1 on WSL2), bash 5.3.9, in a scratch HOME started with env -i. I ran only bash on Linux and only the nodejs plugin. The code involved depends on neither the shell nor the OS, and other plugins that declare legacyFilenames go through the same ParseLegacyFile call, so I expect the same elsewhere, but I have not tried.

Describe the bug
A legacy version file such as .nvmrc or .node-version takes effect when a shell starts in its directory, but not when you cd into that directory from a running shell. And a shell that started in such a directory stays on the file's version when you cd out of it, instead of going back to the global one. A .vfox.toml has neither problem.

At every prompt in such a directory vfox env still calls the plugin's ParseLegacyFile, so vfox does learn what the file says (Found [email protected] below). That answer is not what decides whether the cached output can be reused, so vfox prints the output it cached for the previous directory.

Steps to reproduce
legacyVersionFile.enable is true and legacyVersionFile.strategy is specified, the defaults.

$ vfox add nodejs
$ vfox install [email protected]
$ vfox install [email protected]
$ vfox use -g [email protected]
$ mkdir -p ~/demo/plain ~/demo/with-nvmrc ~/demo/with-toml
$ printf '18.20.8\n' > ~/demo/with-nvmrc/.nvmrc
$ printf '[tools]\nnodejs = "18.20.8"\n' > ~/demo/with-toml/.vfox.toml

Going in: a bash that starts in plain, then cds into the directory with the .nvmrc. The directory with the .vfox.toml switches right away, for comparison:

$ cd ~/demo/plain
$ eval "$(vfox activate bash)"
$ node -v
v26.13.0
$ cd ../with-nvmrc
$ cat .nvmrc
18.20.8
$ node -v
v26.13.0
$ vfox --debug env -s bash 2>&1 | grep -o -E "Parsing legacy file [^ ]+|Found nodejs@[0-9.]+|Config changed: [a-z]+|Using cached output"
Parsing legacy file /home/me/demo/with-nvmrc/.nvmrc
Found [email protected]
Config changed: false
Using cached output
$ cd ../with-toml
$ cat .vfox.toml
[tools]
nodejs = "18.20.8"
$ node -v
v18.20.8

Going out: a bash that starts in the directory with the .nvmrc, then cds to plain:

$ cd ~/demo/with-nvmrc
$ eval "$(vfox activate bash)"
$ node -v
v18.20.8
$ cd ../plain
$ node -v
v18.20.8
$ vfox --debug env -s bash 2>&1 | grep -o -E "Parsing legacy file [^ ]+|Found nodejs@[0-9.]+|Config changed: [a-z]+|Using cached output"
Config changed: false
Using cached output

Root cause
envFlag (cmd/commands/env.go#L147-L197) decides whether it can reuse the output it cached for this shell:

  • It first calls loadToolChain (cmd/commands/tool_resolution.go#L31-L52), which reads the config files and calls ParseLegacyFile for the current directory. A legacy result only goes into the in-memory project config.
  • configPaths then lists only the vfox config files that exist (L154-L164). A directory with only a .nvmrc has no project config file, so the project entry is empty on both sides of the cd.
  • ConfigState.HasChanged (internal/env/state.go#L112-L164) compares that project path with the last one, PATH with the cached PATH, and the modification time of each tracked file with the stored one. In the transcripts none of the three differs (Config changed: false), and envFlag prints the cached output (L189-L197).

So the version file, and the directory it is read from, are inputs of the output that the cache does not know about. AGENTS.md already states the principle for path.mode: the cached output is keyed by the PATH policy "because config.yaml is not among the files whose modification time is tracked; a setting that changes the PATH order has to be part of that key" (L113), and it says that loadToolChain "reads the version files, legacy ones included, for env, activate and doctor" (L90).

Expected behavior
After cd ../with-nvmrc, node -v prints v18.20.8, and after cd ../plain from there it prints v26.13.0 again, as the directory with the .vfox.toml does.

Possible fix
env runs at every prompt (AGENTS.md), so both ideas below are comparisons of values that envFlag already has:

  1. Keep the working directory in the state, the way CachedPathPolicy keeps the PATH policy, and count a different directory as a change. I tried this on v1.0.13: 55 added lines with a test (ConfigState.DirChanged and SetDir, used in envFlag). A shell that went into a .nvmrc directory, a .node-version directory, a plain directory, two .vfox.toml directories and a plain directory again came out right at every step, going out included, also with plugin 0.5.3. It does not notice an edit of the version file in the directory the shell is already in.
  2. Keep what loadToolChain resolved (the tool and version pairs, legacy ones included) and count a different set as a change. envFlag has it before the cache check, so it needs no list of files per plugin, and it should also catch an edit in place. I have not tried this one.
Lingua principale
Go
Stelle
4k
Fork
167
Merge medio
2g 10h
PR unite (30g)
8

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di version-fox/vfox

Tutte le issue di version-fox/vfox

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.