Open pvinis opened 5 years ago
The issue template does not work well with the details.. I tried to fix it but I failed.
Note that nvm is not supported with homebrew - if you brew uninstall it, and install it the proper way (in the readme), do you see the same behavior?
Thanks for the -x
output, but it's not clear to me where it's erroring :-/ it's getting to the nvm_tree_contains_path
call on line 2178 (via the nvm_die_on_prefix
call on line 2995), and the only variable compared with -n
after that is NVM_USE_OUTPUT
- which is declared with local
on line 2977.
The exit code 3
is returned from nvm
in a few places:
nvm ls-remote
fails via nvm_remote_versions
nvm ls
failsnvm_version_dir
fails (called internally, unlikely)nvm_version_path
fails (called internally, unlikely)nvm_version
failsOne possibility is, could you edit nvm.sh
to change every return 3
to a different 2-digit number, and then see which callsite is causing the error?
brew or manual, both give me this exit code.
that's a good idea. I'll try that tomorrow morning since I'm on my phone now.
Is there a reason actually that it returns the same number Ina few places? why not use different numbers for different places and different errors by default?
Typically I use unique numbers for each code path; but as nvm has gotten more complex, they've blurred together a bit. It would be a reasonable (but technically breaking) change to make sure every exit code in the app is unique (at least for things more complex than simple 0/1 predicates).
omg I changed all numbers to unique ones (except the 312 :p)
and it exits with 0.
I'll start putting them back to 3 and see how when it breaks again.
Hm, ok on my home macbook its 0 exit even with a freshly installed one. That's good. Then I'll check tomorrow at work with the problematic machine, and see what could be the issue.
Thanks for your efforts! I’m looking forward to fixing this, and perhaps convincing me it’s time for unique exit codes :-D
I found the reproducible way!
With nvm not in the system, uninstalled, cleared etc, no rc files, no nodes installed, try this:
.nvmrc
nvm.sh
file.
it exits with code 3
that comes from https://github.com/creationix/nvm/blob/master/nvm.sh#L2944.
nvm is correctly sourced, and works fine, but it prints that i need run nvm install
which makes sense, but also returns with 3
.Basically, the problem here is sourcing nvm in a dir that has a .nvmrc
in it. If I install and source outside, then go in the dir, it's fine, and when I do nvm use
it will complain and return 3
, which is great.
I don't know how this should be handled. I am basically trying to setup a project with ci, and in the ci I am already in the dir, and I install nvm, then source nvm, then nvm install, then nvm use. This order would work if sourcing would not try to do nvm use inside it I'm guessing.
What do you think?
Interesting. You can source with --no-use
, or with --install
to autoinstall - does this address it for you?
(I'd expect nvm
to be sourced long before any CI system cd's into a project directory)
I'll try it.
Well, if the ci is using a node image, usually nvm is there already. If it's booting a macos image though, nvm is probably missing, so the init happens, cds in my project and then I get control, when I would start installing nvm and other things that I need.
This might be due to a bug in bash 3 (which ships on Macs) which makes set -e
exit even on tests that exit nonzero.
To be honest, I switched to nodenv since last month. Feel free to keep this issue open to solve this if it's still a problem, or close it if you feel it's not relevant anymore.
nvm, thank you for your service :D
Sorry to hear that :-)
I believe I've solved it with 58d0933f72c3b819d8180e3fe68b66201a87c0a4, so I'll close.
I will try master out of curiosity :D
@ljharb I just tested on Ubuntu 18.04.5 LTS
with version v0.38.0
, and I'm still getting the issue. This is usually a problem in CI environments. For instance, on CircleCI, when using the Node Orb, the installation will fail if you have a .nvmrc
file in the working directory. Removing the .nvmrc
file solves the issue, though. I hope this info is useful, and I'm also attaching an image of the output, which could be useful too 🙂
Cheers!
@JoseLion is this the same setup, then? Circle is sourcing nvm after cd-ing into the project’s directory, and before running nvm install
? If so, this might be something that circle’s image could fix.
I'm not sure I understand why CircleCI's image could fix it 😅 But just for clarity, I'm installing NVM (and NodeJS) manually in the job's steps, which is exactly what the Official Node Orb does:
jobs:
build-web:
working_directory: ~/repo/web
docker:
- image: cimg/base:stable
steps:
- checkout:
path: ~/repo
- run:
name: Install NodeJS
command: |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
source $BASH_ENV
nvm install
nvm alias default
echo 'nvm use default &>/dev/null' >> $BASH_ENV
Any run
command is executed in the working_directory
where the .nvmrc
file usually is. I'm actually trying to use that file when nvm install
and nvm alias default
are executed. Of course, as a workaround, I can do cd ..
just before fetching the installer and set the NodeJS version manually in the command, but that's not ideal if I already have a file to track and centralize the version, right?
Also, it would be harder to for the Official Node Orb to use this workaround since it would have to check the working directory for a .nvmrc
file and do cd <somewhere?>
if the file exists. Which again, it's not ideal because not all projects will have the .nvmrc
file.
I really hope this helps to clarify the issue, NVM is a great tool and the .nvmrc
file is very helpful too! 🙂
Right - the issue is that nvm expects that if an .nvmrc file is present with a node version in it, that before cd-ing into that directory, you'd source nvm. So, in your case, you can change to this:
command: |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --install' >> $BASH_ENV
source $BASH_ENV
(note that nvm alias default
just echoes the current default alias, and that the nvm use default
seems unnecessary)
@ljharb got you, that makes sense! I used --install
as you suggested, and it worked perfectly. 👍🏼
Do you think it would be possible to add a fix for this? Probably ignoring the .nvmrc
file when nvm.sh
is sourced? (I'm not sure if that would break other features, though 🤔). If not, probably it's something worth adding to the documentation to help other folks understand what could cause this exit code 3
issue, WDYT? 🙂
It would break other features, unfortunately :-/ specifically, the feature to auto-use the nvmrc version at source time, which in non-CI use cases, is already installed.
There may be a way to either detect CI, and do something different; or, only when sourcing nvm.sh, avoid failing when an nvmrc version is not present.
That would be awesome! Thanks 🙂 🎉
I’m experiencing this issue in our Platform.sh configuration. Here’s what we’re running (following the most recently-suggested solution above):
hooks:
build: |
set -e
unset NPM_CONFIG_PREFIX
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.38.0/install.sh | dash
# Add required environment variables to profile.
echo 'export NVM_DIR="$PLATFORM_APP_DIR/.nvm"' >> $PLATFORM_APP_DIR/.profile
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --install' >> $PLATFORM_APP_DIR/.profile
# Source profile.
. $PLATFORM_APP_DIR/.profile
nvm current
# TODO: Specifying the version should not be necessary, but Platform
# builds fail without a specific version.
nvm install
nvm use
nvm install-latest-npm
_(Note that in Platform.sh environments, $PLATFORM_APP_DIR
resolves to the directory where our application is installed.)_
nvm is exiting with 3. What am I missing?
@agarzola what jumps out at me:
nvm install --latest-npm
covers all the last three lines.Hi,
FWIW I'm experiencing this very same issue on macOS + Zsh when manually sourcing nvm.sh
by following the official instructions:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Stack versions:
NVM: 0.38.0
Zsh: zsh 5.8 (x86_64-apple-darwin20.1.0)
macOS: 11.4
npm:
{
npm: '7.18.1',
node: '16.4.2',
v8: '9.1.269.36-node.14',
uv: '1.41.0',
zlib: '1.2.11',
brotli: '1.0.9',
ares: '1.17.1',
modules: '93',
nghttp2: '1.42.0',
napi: '8',
llhttp: '6.0.2',
openssl: '1.1.1k+quic',
cldr: '39.0',
icu: '69.1',
tz: '2021a',
unicode: '13.0',
ngtcp2: '0.1.0-DEV',
nghttp3: '0.1.0-DEV'
}
The interesting thing however is that everything seems to be working as expected, as I was able to correctly install latest 16.4.2
Node version.
I only got aware of nvm.sh
sourcing exiting with code 3 when I decided to load NVM on-demand from the shell, instead of by automatically sourcing it on each new shell session to avoid the noticeable lag hit.
I'm pretty much new to Node and NVM, please let me know if I can help by providing additional info or logs.
Thanks!
@agarzola what jumps out at me:
* the install script should add lines to your profile file already, using the default NVM_DIR - try setting NVM_DIR before running the install script, and you may not need the profile lines at all * nvm use is not needed; nvm install auto-uses * `nvm install --latest-npm` covers all the last three lines.
@ljharb Thanks for the assist! Setting NVM_DIR
before installation seems like it helped it find .profile
, which is an improvement. It’s still exiting with code 3, however.
Here’s the updated command:
hooks:
build: |
set -e
unset NPM_CONFIG_PREFIX
# Create .profile in the home directory.
touch $PLATFORM_APP_DIR/.profile
export NVM_DIR="$PLATFORM_APP_DIR/.nvm"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.38.0/install.sh | dash
# Source .profile from home directory.
. $PLATFORM_APP_DIR/.profile
nvm current
# Install and use Node version specified in .nvmrc.
nvm install --latest-npm
It still exits w/code 3. 🤔
Another update on this. I set -x
(technically, set -ex
) and it appears our script is failing on sourcing .profile
. The logs show that it does not get to the like where we invoke nvm current
, which means the script dies when sourcing /app/.profile
:
Executing build hook...
W: + unset NPM_CONFIG_PREFIX
W: + touch /app/.profile
W: + export NVM_DIR=/app/.nvm
W: + curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.38.0/install.sh
W: + dash
W: % Total % Received % Xferd Average Speed Time Time Time Current
W: Dload Upload Total Spent Left Speed
100 14926 100 14926 0 0 5116 0 0:00:02 0:00:02 --:--:-- 5116
=> Downloading nvm from git to '/app/.nvm'
W: Cloning into '/app/.nvm'...
=> * (HEAD detached at FETCH_HEAD)
master
=> Compressing and cleaning up git repository
=> Appending nvm source string to /app/.profile
=> bash_completion source string already in /app/.profile
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
W: + . /app/.profile
W: + export NVM_DIR=/app/.nvm
W: + [ -s /app/.nvm/nvm.sh ]
W: + . /app/.nvm/nvm.sh
W: + NVM_SCRIPT_SOURCE=
… (a lot more commands that seem to come from nvm.sh)
E: Error building project: Step failed with status code 3.
The issue is that you’re setting -e; you shouldn’t be (largely ever). nvm does not survive that mode.
From what I read here, the "real" problem is that nvm is reporting an error situation (the node version requested in .nvmrc is not found on the system), but it's not telling very clearly what's going on. Some suggestions that would improve the situation:
--install
"I got bit by this issue too. I was happily running a build script on my own host, and it succeeded, presumably because I had tested it step by step so the required node version was already available. On CI machine, the same script fails with 3, because it doesn't have any nvm steps pre-made. In this way, the . $NVM_DIR/nvm.sh is not truly idempotent.
The first bullet point is a nonstarter; if the docs are wrong then those should be fixed.
One solution might be to disable set -e
(which the nvm
function itself already does) which might prevent the erroneous early termination, which would actually show a better error message.
If after that, the error message still needs improvement, I'd be happy to review a PR that improved it.
the . $NVM_DIR/nvm.sh is not truly idempotent.
It's not expected to be nor is it declared as such anywhere.
I am having this issue now when installing nvm in my jenkins pipeline... I'm circumventing this by changing the directory before install... Sucks this is still a thing
@AngelODeath try unsettling the e option.
I wanted to install nvm in a CI/CD environment in a docker image.
It took me ~2-3 hours, to figure out what the problem is.
I had only an exit code 3
.
Without a proper error message what the problem is, and how to solve it.
In the nvm.sh
there are 2 exit(3)
occurrences and 23 return 3
occurrences.
I totally agree with the suggestions made by @pkalliok-aiven commented on Aug 27 2021.
For me the source "${NVM_DIR}/nvm.sh" --install
solved the problem.
i ran into this problem on CircleCI when trying to source the nvm.sh
file in the project directory (where an .nvmrc
file is present).
it would exit with error code 3 and no helpful message.
~i solved it~ by explicitly setting the NVM_DIR
variable before sourcing nvm.sh
echo 'export NVM_DIR=~/.nvm' >> $BASH_ENV
echo 'source ~/.nvm/nvm.sh' >> $BASH_ENV
source $BASH_ENV
edit: looks like this didn't fix it after all...
https://github.com/nvm-sh/nvm/issues/1985#issuecomment-907332697 remains my position; a PR to improve the error message would be much appreciated.
it turns out my fix (defining NVM_DIR before sourcing nvm.sh) didn't actually fix it...
The issue is that you’re setting -e; you shouldn’t be (largely ever). nvm does not survive that mode. this
that option is being set by circleci when executing the build. it is helpful to have the build stop when the build script encounters an error.
more philosophically, it seems pretty counterintuitive that the nvm.sh
script would fail prematurely simply due to the presence of another completely valid and core nvm-related file (.nvmrc
).
a helpful error message would spare debugging time but it still requires the user to jump through weird hoops to get it to work.
if there is already a command line option (--install
) to explicitly install node in the same step as sourcing, it feels like it would make sense for the default behaviour (without that option) to simply ignore an .nvmrc
file
if that doesn't make sense to be the default behaviour, then a new option (i.e. --ignore-nvmrc
) would be equally helpful in overcoming this issue.
as it stands, the .nvm.sh
script is failing prematurely which may not be a problem for the time being (since apparently nothing important happens after the failure), but it feels brittle/dangerous to assume this will always be the case.
in other words, if the premature failure is indeed irrelevant, one could argue it should "fail" with a zero status code and a warning logged to the console
You can unset it in your circle config, no?
I completely agree that a helpful error message isn't as good as improving the core problem, but it's a start.
The default behavior is "use", the optional behavior is "install". Both (must) read .nvmrc
when present.
I think the action items here are initially to improve the error message.
After that is completed, it's worth considering some of these options:
set -e
, because enabling it is a widespread bad practice--install
to the sourcing options in your profile file, which would result in you actually getting the node version you wanti tried adding --install
as you suggested in line 4 and tested it out on my local workstation.
it looks like it's attempting to install the wrong version of node (see below)...
notice the project .nvmrc
file contains 16.2.0 but the source nvm.sh
step is reporting 10.4.0
M-14292:~/projects/member-management-ui$ nvm ls
-> v10.4.0
v10.14.2
v12.10.0
v12.18.4
v12.20.0
v14.15.4
v16.2.0
default -> 10.4.0 (-> v10.4.0)
node -> stable (-> v16.2.0) (default)
stable -> 16.2 (-> v16.2.0) (default)
iojs -> N/A (default)
unstable -> N/A (default)
lts/* -> lts/gallium (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.10 (-> N/A)
lts/fermium -> v14.19.0 (-> N/A)
lts/gallium -> v16.14.1 (-> N/A)
M-14292:~/projects/member-management-ui$ cat .nvmrc
16.2.0
M-14292:~/projects/member-management-ui$ . ~/.nvm/nvm.sh --install
v10.4.0 is already installed.
M-14292:~/projects/member-management-ui$ echo $?
0
ah, the default
alias takes precedence over .nvmrc
when present. If you nvm unalias default
you should be closer to the state CI is in.
Still running into this issue with v0.39.4. My workaround is to rename .nvmrc, source nvm, then rename back. This is my Makefile target:
nvm:
# Have to rename .nvmrc then source nvm or it errors, see https://github.com/nvm-sh/nvm/issues/1985#issuecomment-456022013
mv .nvmrc .nvmrc_temp
# Need source nvm this way in make, see https://github.com/nvm-sh/nvm/issues/1446#issuecomment-816446454
. ${NVM_DIR}/nvm.sh && mv .nvmrc_temp .nvmrc && nvm install && nvm use
@omarrelativity you can source it with --no-use
and skip the nvmrc rename step, and if you source it with --install
instead, it'll do all that in one go for you.
I tried both options already, still get Error 3:
nvm-install:
. ${NVM_DIR}/nvm.sh --install
nvm-no-use:
. ${NVM_DIR}/nvm.sh --no-use
and you have +e
set, since -e
isn't a good thing to be enabling? if so, then that's a legitimate bug i'd love more info on.
I'm not sure what is set, I'm running this in a simple ubuntu:latest
Docker container with nvm/curl/make/azure-cli/pulumi installed. Makefile doesn't have anything fancy in it.
$SHELLOPTS shows braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
Doing echo $$SHELLOPTS
in the Makefile shows an empty line as output.
@omarrelativity i think this warrants a separate issue, since those sourcing options should work. mind filing it?
Issue created https://github.com/nvm-sh/nvm/issues/3177
I encountered this and under the same conditions I also reproduced #1769, so I think these issues are related, maybe duplicates depending on the root cause.
Still encountering this while trying to install NVM in a Dockerfile based on Debian bullseye.
When I source
nvm.sh
like. "$HOME/.nvm/nvm.sh"
for manual install and like. $(brew --prefix nvm)/nvm.sh
, the exit code is3
.Even though nvm works after that, in bash scripts with
set -e
, the script stops there, since the command exits with a non-zero value.Is there a reason this fails? Is there a reason it exits with
3
, if it's not an actual failure? What can we do about that?Some extra info:
output of
. nvm.sh
withset -x
for "tracing": https://pastebin.com/raw/1Tk9UUspOperating system and version: macOS 10.14.2 (mojave)
nvm debug
output:Details
nvm ls
output:Details
How did you install
nvm
? (e.g. install script in readme, Homebrew): Tried both. I mostly do from brew though, since it's easier.What steps did you perform? source the file
What happened? worked, but exits with non-zero value
What did you expect to happen? to exit with a 0 value since everything seemingly went well
Is there anything in any of your profile files (
.bashrc
,.bash_profile
,.zshrc
, etc) that modifies thePATH
? I ran this without any $PATH alterations. In general I don't have anything in there that touch nvm. Only to includebrew
stuff.