[Fix] nvm use: do not pile up PATH entries in nested sessions

`nvm_change_path` prepends the new version
(instead of replacing the existing nvm path)
when a system bin dir precedes an nvm path,
to handle macOS `path_helper` reordering the `PATH` of nested sessions
(#1652). However, the check matched a system dir followed by *any* nvm path.
Once a stale nvm path sits after the system dirs
(e.g. inherited by a nested shell, tmux, or an editor's terminal),
the check stays true forever,
so every `nvm use` prepends yet another entry and the previously used version is never removed from the `PATH`.

Only consider the first nvm path:
if it is not preceded by a system bin dir,
replace it in place as usual.

Fixes #3561
This commit is contained in:
maliv2 authored and Jordan Harband committed 2026-10-14 20:53:08 +03:00
1 parent 799de1d2dc
commit bfabdbc278
2 files changed
+18 -4

No files matched your search

+5 -4
View File
@@ -1556,11 +1556,12 @@ nvm_change_path() {
&& ! nvm_echo "${1-}" | nvm_grep -Eq "${NVM_DIR_RE}/versions/[^/]*/[^/]*${2-}"; then
nvm_echo "${3-}${2-}:${1-}"
# if the initial path contains BOTH an nvm path (checked for above) and
# that nvm path is preceded by a system binary path, just prepend the
# supplementary path instead of replacing it.
# the first nvm path is preceded by a system binary path, just prepend the
# supplementary path instead of replacing it. Only what precedes the first
# nvm path counts, so that a shadowed nvm path further on does not make
# every change prepend yet another entry.
# https://github.com/nvm-sh/nvm/issues/1652#issuecomment-342571223
elif nvm_echo "${1-}" | nvm_grep -Eq "(^|:)(/usr(/local)?)?${2-}:.*${NVM_DIR_RE}/[^/]*${2-}" \
|| nvm_echo "${1-}" | nvm_grep -Eq "(^|:)(/usr(/local)?)?${2-}:.*${NVM_DIR_RE}/versions/[^/]*/[^/]*${2-}"; then
elif nvm_echo "${1%%"${NVM_DIR}"/*}" | nvm_grep -Eq "(^|:)(/usr(/local)?)?${2-}:"; then
nvm_echo "${3-}${2-}:${1-}"
# use sed to replace the existing nvm path with the supplementary path. This
# preserves the order of the path.
+13
View File
@@ -70,3 +70,16 @@ NEW_PATH=`nvm_change_path "$MAC_OS_NESTED_SESSION_PATH" "/bin" "$NVM_DIR/version
NEW_PATH=`nvm_change_path "$MAC_OS_NESTED_SESSION_PATH" "/bin" "$NVM_DIR/v0.1.2"`
[ "$NEW_PATH" = "$NVM_DIR/v0.1.2/bin:/usr/bin:/usr/local/bin:$NVM_DIR/versions/node/v4.5.0/bin" ] || die "Not correctly changed: $NEW_PATH "
# an nvm path that was already prepended ahead of the system paths is replaced,
# rather than piling up another entry on every change
# https://github.com/nvm-sh/nvm/issues/3561
PREPENDED_NESTED_SESSION_PATH=$NVM_DIR/versions/node/v7.1.0/bin:/usr/bin:/usr/local/bin:$NVM_DIR/versions/node/v4.5.0/bin
NEW_PATH=`nvm_change_path "$PREPENDED_NESTED_SESSION_PATH" "/bin" "$NVM_DIR/versions/node/v8.0.0"`
[ "$NEW_PATH" = "$NVM_DIR/versions/node/v8.0.0/bin:/usr/bin:/usr/local/bin:$NVM_DIR/versions/node/v4.5.0/bin" ] || die "Not correctly changed: $NEW_PATH "
NEW_PATH=`nvm_change_path "$PREPENDED_NESTED_SESSION_PATH" "/bin" "$NVM_DIR/v0.1.2"`
[ "$NEW_PATH" = "$NVM_DIR/v0.1.2/bin:/usr/bin:/usr/local/bin:$NVM_DIR/versions/node/v4.5.0/bin" ] || die "Not correctly changed: $NEW_PATH "