node
node copied to clipboard
GitHub action for Windows fails with module not found error for node 22
Version
22
Platform
Windows
Subsystem
No response
What steps will reproduce the bug?
npm install command is enough to reproduce the issue.
Example workflow: https://github.com/CycloneDX/cdxgen/actions/runs/8823813113/job/24236408405#step:10:18
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
No response
What do you see instead?
node:internal/modules/cjs/loader:1205
throw err;
^
Error: Cannot find module 'C:\npm\prefix\node_modules\npm\bin\npm-cli.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1202:15)
at Module._load (node:internal/modules/cjs/loader:1027:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:187:14)
at node:internal/main/run_main_module:28:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Additional information
No response
For your information, I have the same problem on my Windows machine, so it's not just a problem with Github actions
PS C:\Users\me> node --version
v22.0.0
PS C:\Users\me> npm --version
node:internal/modules/cjs/loader:1205
throw err;
^
Error: Cannot find module 'C:\Users\me\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1202:15)
at Module._load (node:internal/modules/cjs/loader:1027:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:187:14)
at node:internal/main/run_main_module:28:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
I am also experiencing this.
@Thanaen
- How did you install/update Node.js?
- Does
C:\Users\me\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js
exist on your system?
I'm currently not able to reproduce on my Windows machine. I tried:
- With
Volta
version manager (my usual setup) - With the offitial
.msi
installer (in a Windows Sandbox)
C:\Users\WDAGUtilityAccount>node -v
v22.0.0
C:\Users\WDAGUtilityAccount>npm -v
10.5.1
@targos I updated Node via the node-v22.0.0-x64 installer, downloaded directly from the Node website.
When I saw that it didn't work, I uninstalled Node, then did a clean install, with the same installer file. (after cleaning up all the cache files etc)
I then tried activating corepack and installing npm via corepack (corepack enable
then corepack prepare npm@latest --activate
)
After checking, it seems that the C:\Users\me\AppData\Roaming\npm
folder doesn't exist 😅
Also, I've changed the npm_config_cache
environment variable to point to my Dev Drive, so maybe that's a factor?
PS: I've tried removing my environment variable, but it doesn't fix the problem
@targos I've just tried installation via Volta, and npm works correctly. Maybe a problem with the MSI installer and Windows 11?
I don't know how to reproduce on my Windows system but it seems indeed to be a general issue on GitHub actions (which download the binary from https://nodejs.org/dist/v22.0.0/node-v22.0.0-win-x64.7z): https://github.com/nodejs/citgm/actions/runs/8831148407/job/24245743480?pr=1056
have the same issue
The main difference I see between v20/v21 and v22 is the presence of npm.ps1
and npx.ps1
in the distribution.
This is from https://github.com/nodejs/node/pull/52009
/cc @nodejs/npm @lukekarrys
Also /cc @StefanStojanovic.
I'm trying to find a simple reproduction but I hit another problem. Here are the steps I took:
- Download v22 from https://nodejs.org/download/release/v22.0.0/ (I used the
-arm64.zip
one) - Extract it and cd into it.
- Run:
PowerShell 7.4.2
PS C:\Users\mzasso\Documents\node-v22.0.0-win-arm64\node-v22.0.0-win-arm64> .\node.exe -v
v22.0.0
PS C:\Users\mzasso\Documents\node-v22.0.0-win-arm64\node-v22.0.0-win-arm64> .\npm.cmd -v
10.5.1
PS C:\Users\mzasso\Documents\node-v22.0.0-win-arm64\node-v22.0.0-win-arm64> .\npm.ps1 -v
node.exe not found.
Suggestion [3,General]: The command "node.exe" was not found, but does exist in the current location.
PowerShell does not load commands from the current location by default (see ''Get-Help about_Command_Precedence'').
If you trust this command, run the following command instead:
PS C:\Users\mzasso\Documents\node-v22.0.0-win-arm64\node-v22.0.0-win-arm64>
Then I installed a global node.exe with Volta and hit another (still different, but similar) issue:
PS C:\Users\mzasso\Documents\node-v22.0.0-win-arm64\node-v22.0.0-win-arm64> .\npm.ps1 -v
node:internal/modules/cjs/loader:1205
throw err;
^
Error: Cannot find module 'C:\Program Files\Volta\node_modules\npm\bin\npm-prefix.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1202:15)
at Module._load (node:internal/modules/cjs/loader:1027:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:187:14)
at node:internal/main/run_main_module:28:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v22.0.0
Could not determine Node.js install directory
Maybe the problem is that the npm.ps1
script tries to determine where npm is installed based on where the global node.exe is installed? This seems wrong.
This appears to be a problem w/ the base node installation in windows itself.
A related issue is https://github.com/npm/cli/issues/6971
It seems that in some installations npm does not end up where it belongs? Or is missing directories?
Maybe the problem is that the npm.ps1 script tries to determine where npm is installed based on where the global node.exe is installed?
No, it tries to ask windows where node.exe is
$nodebin = $(Get-Command $nodeexe -ErrorAction SilentlyContinue -ErrorVariable F).Source
It then looks to the parent folder of the node executable and starts looking for npm there
$nodedir = $(New-Object -ComObject Scripting.FileSystemObject).GetFile("$nodebin").ParentFolder.Path
That's why this is happening
Suggestion [3,General]: The command "node.exe" was not found, but does exist in the current location. PowerShell does not load commands from the current location by default (see ''Get-Help about_Command_Precedence'')
There is no node
executable that is in a valid path. Windows is refusing to consider the one in the cwd as valid when npm asks for it because of command precedence.
npm.cmd
looks for node using %~dp0\node.exe
. Is it getting a different answer for this than Get-Command
?
npm.cmd
looks for node using%~dp0\node.exe
. Is it getting a different answer for this thanGet-Command
?
Yes. %~dp0
is the directory that contains npm.cmd
npm has to make an assumption that npm
and node
are in the same place, and based on that can go find itself. npm.cmd
and corepack
do this by evaluating %~dp0\node.exe
. npm.ps1
does this by calling Get-Command node.exe
.
Is there another node.exe that is in the path? How do these strings materially differ, shouldn't they be the same?
It looks like that difference is the root cause here. We'll keep this issue open to track the work instead of making duplicates.
While we're on the subject however, it appears that this npm.ps1
file is not properly digitally signed in the node installation. cf https://github.com/npm/cli/issues/7280.
This may represent a larger issue that has to date gone unnoticed. What npm is trying to make sure of is that node
and npm
are both reached by the same method. If there is some other node installation that is called when a person runs node
that differs than the one npm shipped with that could cause problems. There is no guarantee that other version of node even works with this version of npm.
If Get-Command node.exe
is not returning the same node.exe that is alongside the file that runs when npm.ps1
is called, that is an issue. It seems like it's an issue w/ the installer in that it's not putting the version of node that was installed properly in the user's PATH.
In the short term, we'll update the .ps1
script to use %dp0
, @lukekarrys is working on this.
npm.cmd
looks for node using%~dp0\node.exe
. Is it getting a different answer for this thanGet-Command
?Yes.
%~dp0
is the directory that containsnpm.cmd
I think this is a mistake in the ps1 scripts that npm
ships with then. They should be using %~dp0
instead of Get-Command
. I'll make a PR to npm fixing this in npm.ps1
and npx.ps1
.
It appears that this npm.ps1 file is not properly digitally signed in the node installation. cf https://github.com/npm/cli/issues/7280.
I would be curious if anyone knows how to fix the issue with digitally signing the ps1 scripts. I don't think it's directly related to this issue, but v22 is the first time these scripts are included in the Node installer. I'm not sure if this is something that should be fixed on the npm or node side.
%~dp0
is a .cmd/batch file thing. Powershell equivalents (depending on the version being targetted): https://stackoverflow.com/a/36417541
As for signing, Node.js signs assets it produces (the node.exe
file, and msi installer). The logic for that is in vcbuild.bat
. However, I'd be a little wary of using Node.js' signing certificate to sign something originating from outside of Node.js.
This is the expected error if the image just didn't set the path
As for signing, Node.js signs assets it produces (the
node.exe
file, and msi installer). The logic for that is invcbuild.bat
. However, I'd be a little wary of using Node.js' signing certificate to sign something originating from outside of Node.js.
Thanks, that's good to know. I don't love the idea either of Node signing a file that lives in the npm repo. Maybe a dumb question, but what would it take for Node to own this Powershell script? I don't have any of the historical context here, but AFAIK npm doesn't do anything special with those files beyond ensuring they exist. If those files were moved to Node we would just shift the implicit contract to ensuring the files referenced within the Powershell script existed.
This is off topic for this discussion but I'd like to continue it (in a new issue probably).
I have a PR open that should fix this issue: https://github.com/npm/cli/pull/7422
I'm no Powershell expert but I think I was able to match the behavior in the bin/npm
bash script.
We do have tests for these scripts that ensure they run, but they assume a fixed location of node.exe
. If anyone would like to review the PR from the perspective of how this file will be run from a user's machine after being placed by the Node installer, that would be greatly appreciated.
I have a PR open that should fix this issue: npm/cli#7422
I'm no Powershell expert but I think I was able to match the behavior in the
bin/npm
bash script.We do have tests for these scripts that ensure they run, but they assume a fixed location of
node.exe
. If anyone would like to review the PR from the perspective of how this file will be run from a user's machine after being placed by the Node installer, that would be greatly appreciated.
@nodejs/platform-windows
I tried the script from https://github.com/npm/cli/pull/7422 with my repro steps and it works.
$ npm -v
node:internal/modules/cjs/loader:1205
throw err;
^
Error: Cannot find module 'C:\Users\<username>\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1202:15)
at Module._load (node:internal/modules/cjs/loader:1027:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:187:14)
at node:internal/main/run_main_module:28:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v22.0.0
You have to copy C:\Program Files\nodejs\node_modules\npm
to %AppData%\Roaming\npm\node_modules
temporarily.
I think this issue only occurs on:
- Fresh installation of Node v22
- Upgraded to Node v22 but never installed npm globally (
npm i -g npm
) before
The new npm script seems to only check global installation by default and will not use the version bundled in the Node installation directory.
https://github.com/actions/node-versions/releases/tag/22.0.0-8879734543
- Still generates the same error in GitHub Actions.
@cclauss that build is from 5 hours ago but the fix was only merged 2 hours ago.
The fix was merged in npm but has not been released yet. Our goal is to release it today. After that happens we will make a new PR to Node which should then fix this issue.
For visibility, I wanted to surface another bug found in the new npm Powershell scripts that shipped with v22, since folks watching this issue might hit this one as well.
The full details are here (https://github.com/npm/cli/issues/7375#issuecomment-2083924657) but the gist is argument parsing is different between batch/cmd files and powershell, so attempting to call a run script like npm run echo -- arg1 --arg2
will not pass the --arg2
along due to the leading dashes.
To get the same behavior in Powershell you need to run npm run echo --% arg1 --arg2
. Edit: this is not fully equivalent. See the linked issue fore more details.
So far I have not been able to fix this in npm's Powershell shim to get parity with the batch file. If this is not possible, then npm might chose to remove the PS1 shims and send a PR to remove them from the Node installer as well.