Skip to content

Conversation

@tennisleng
Copy link

Summary

Fixes #3727

When no node versions are installed, nvm ls produces errors like:

find: /path/.nvm/versions/node/*: No such file or directory

This happens because bash expands * literally when nullglob is not set and the directory is empty.

Solution

  • Build find arguments dynamically without shell glob expansion
  • Use find DIR -mindepth 1 -maxdepth 1 instead of find DIR/*
  • Suppress stderr from find to handle edge cases gracefully
  • Deduplicate directories before passing to find

Before

$ nvm ls
find: /Users/balupton/.nvm/versions/node/*: No such file or directory
find: /Users/balupton/.nvm/versions/node/*: No such file or directory
-> system

After

$ nvm ls
-> system

Testing

  • Verified with empty ~/.nvm/versions/node/ directory
  • Verified with existing node versions installed

@ljharb
Copy link
Member

ljharb commented Dec 5, 2025

Instead of altering a bunch of the logic, could we perhaps just disable nullglob when needed for the nvm_ls invocation?

@tennisleng tennisleng force-pushed the fix/nullglob-find-errors branch from 1a95084 to da2a20f Compare December 5, 2025 19:51
…ions installed

Fixes nvm-sh#3727

When no node versions are installed, nvm ls produces errors like:
`find: /path/.nvm/versions/node/*: No such file or directory`

This happens because bash expands `*` literally when nullglob is not
set and the directory is empty.

Solution:
- For bash: temporarily enable nullglob before the find command
- For other shells (sh, dash, zsh): suppress stderr (2>/dev/null)
- Restore nullglob to its previous state after the command completes
- Uses BASH_VERSION check to detect bash vs other shells
@tennisleng tennisleng force-pushed the fix/nullglob-find-errors branch from da2a20f to 9449392 Compare December 5, 2025 19:55
@ljharb
Copy link
Member

ljharb commented Dec 5, 2025

so this kind of works, but relies on nothing exiting prior to the restoration.

i was thinking instead, of wrapping every call to nvm_ls in this nullglob check, and turning it off in a subshell in which nvm_ls is invoked - that way, it's impossible have the nullglob change persist.

Move nullglob enabling into the command substitution subshell so that
the shell option change cannot persist to the parent shell, even if
something exits early. This is a safer approach than save/restore.

The subshell automatically cleans up when it exits, making it impossible
for nullglob to leak into the user's shell environment.
@ljharb
Copy link
Member

ljharb commented Dec 5, 2025

Awesome! Now we need a test that has the wrong nullglob setting and will prevent regressions :-)

Adds a test that explicitly disables nullglob and runs nvm ls with
an empty versions directory to ensure the fix prevents regressions.

The test verifies:
- nvm ls does not produce 'No such file or directory' errors
- nvm ls exits with code 0 when no versions are installed
@tennisleng
Copy link
Author

Awesome! Now we need a test that has the wrong nullglob setting and will prevent regressions :-)

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nvm depends on nullglob but doesn't require nor set it

2 participants