cli
cli copied to clipboard
[BUG] Cannot set property 'peer' of null
Is there an existing issue for this?
- [X] I have searched the existing issues
This issue exists in the latest npm version
- [X] I am using the latest npm
Current Behavior
I can only hit this particular error in a certain directory with a certain package, but I can reproduce it over several npm versions and it's 100% of the time.
There are more examples available in #3711 (the author refuses to reopen the bug even though it is not fixed and people are hitting it!).
After having a working npm for years and not changing the config, I just ran into it on npm v8.1.4. Upgraded to v8.5.4 and the problem did not go away. Here's the log with the latest version (8.12.1):
0 verbose cli C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js
1 info using [email protected]
2 info using [email protected]
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 1ms
5 timing config:load:file:C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\npmrc Completed in 5ms
6 timing config:load:builtin Completed in 5ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:C:\Users\<user>\tmp\.npmrc Completed in 1ms
10 timing config:load:project Completed in 8ms
11 timing config:load:file:C:\Users\<user>\.npmrc Completed in 3ms
12 timing config:load:user Completed in 3ms
13 timing config:load:file:C:\Program Files\nodejs\etc\npmrc Completed in 3ms
14 timing config:load:global Completed in 3ms
15 timing config:load:validate Completed in 2ms
16 timing config:load:credentials Completed in 1ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 29ms
19 timing npm:load:configload Completed in 30ms
20 timing npm:load:mkdirpcache Completed in 3ms
21 timing npm:load:mkdirplogs Completed in 3ms
22 verbose title npm i <package>
23 verbose argv "i" "<package>"
24 timing npm:load:setTitle Completed in 2ms
25 timing config:load:flatten Completed in 4ms
26 timing npm:load:display Completed in 4ms
27 verbose logfile logs-max:10 dir:C:\Users\<user>\AppData\Local\npm-cache\_logs
28 verbose logfile C:\Users\<user>\AppData\Local\npm-cache\_logs\2022-06-10T07_31_26_930Z-debug-0.log
29 timing npm:load:logFile Completed in 8ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 52ms
33 timing arborist:ctor Completed in 1ms
34 silly logfile start cleaning logs, removing 1 files
35 silly logfile done cleaning log files
36 timing idealTree:init Completed in 81ms
37 timing idealTree:userRequests Completed in 2ms
38 silly idealTree buildDeps
39 silly fetch manifest <package>
40 http fetch GET 200 <repository> 327ms (cache revalidated)
41 silly placeDep ROOT <package> REPLACE for: want: <version>
42 timing idealTree:#root Completed in 349ms
43 timing idealTree:node_modules/<package> Completed in 0ms
44 timing idealTree:node_modules/<package>/vendor/angular Completed in 0ms
45 timing idealTree:buildDeps Completed in 351ms
46 timing idealTree Completed in 436ms
47 timing command:i Completed in 446ms
48 verbose stack TypeError: Cannot set properties of null (setting 'peer')
48 verbose stack at visit (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:104:54)
48 verbose stack at visitNode (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:58:25)
48 verbose stack at next (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:44:19)
48 verbose stack at depth (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:83:10)
48 verbose stack at depth (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\treeverse\lib\depth.js:27:12)
48 verbose stack at unsetFlag (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:99:5)
48 verbose stack at C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:65:7
48 verbose stack at Map.forEach (<anonymous>)
48 verbose stack at calcDepFlagsStep (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:41:17)
48 verbose stack at visit (C:\Users\<user>\AppData\Roaming\nvm\v17.2.0\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:12:20)
49 verbose cwd C:\Users\<user>\tmp
50 verbose Windows_NT 10.0.19042
51 verbose node v17.2.0
52 verbose npm v8.12.1
53 error Cannot set properties of null (setting 'peer')
54 verbose exit 1
55 timing npm Completed in 1259ms
56 verbose unfinished npm timer reify 1654846300239
57 verbose unfinished npm timer reify:loadTrees 1654846300299
58 verbose unfinished npm timer idealTree:fixDepFlags 1654846306426
59 verbose code 1
60 error A complete log of this run can be found in:
60 error C:\Users\<user>\AppData\Local\npm-cache\_logs\2022-05-30T07_24_36_788Z-debug-0.log
I redacted the user and package name as they are company internals. I use a company artifactory with npm registry. However, this has worked for me before and is working for thousands of our developers as we speak, so I think it's a local problem with my npm.
Expected Behavior
npm i <package> installs the package successfully
Steps To Reproduce
- In this environment...
- With this config...
- Run '...'
- See error...
Environment
- npm: v8.12.1
- Node.js: v17.2.0
- OS Name: Windows 10 x64
- npm config:
; copy and paste output from `npm config ls` here
; "user" config from C:\Users\<user>\.npmrc
registry = "<registry>"
strict-ssl = false
; node bin location = C:\Program Files\nodejs\node.exe
; node version = v17.2.0
; npm local prefix = C:\Users\<user>\tmp
; npm version = 8.12.1
; cwd = C:\Users\<user>\tmp
; HOME = C:\Users\<user>
; Run `npm config ls -l` to show all defaults
Specific steps to reproduce:
git clone [email protected]:oguimbal/pgsql-ast-parser.git
cd pgsql-ast-parser
npm i; npm run build # this makes a dist build with a `package.json` in ./lib
cd ..
mkdir npm-cli-issue-5007-repro
cd npm-cli-issue-5007-repro
npm init -y
npm i -S pg-mem ../pgsql-ast-parser/lib
... then edit package.json to insert this:
"overrides": {
"pg-mem": {
"pgsql-ast-parser": "$pgsql-ast-parser"
}
}
... then:
npm i
npm i # yes, again
The second (and any subsequent) npm i execution fails as shown above. Specifically, the unsetFlag node visitor encounters this node which has target: null:
ArboristLink {
name: 'pgsql-ast-parser',
packageName: 'lib',
location: 'node_modules/pg-mem/node_modules/pgsql-ast-parser',
path: '/Users/gthb/git/npm-cli-issue-5007-repro/node_modules/pg-mem/node_modules/pgsql-ast-parser',
realpath: '/Users/gthb/git/npm-cli-issue-5007-repro/node_modules/pgsql-ast-parser/lib',
resolved: 'file:../../pgsql-ast-parser/lib',
dev: true,
optional: true,
overrides: Map(2) { 'pgsql-ast-parser' => '$pgsql-ast-parser', 'pg-mem' => '' },
edgesIn: Set(1) { { node_modules/pg-mem prod pgsql-ast-parser@^10.5.2 } },
target: null
}
There seems to be a lot going wrong there :-) ... (not all of it necessarily relevant to this bug, but some of it for sure):
- the
packageNameis'lib', presumably the last path element of the path I specified ... but thatlibfolder contains apackage.jsonwith"name": "pgsql-ast-parser"— should that not be thepackageNamevalue? - the
locationis'node_modules/pg-mem/node_modules/pgsql-ast-parser'and that path does exist ... but it's a symlink pointing to../../pgsql-ast-parser/libwhich resolves tonode_modules/pgsql-ast-parser/lib - ... and sure enough, the
realpathis'/Users/gthb/git/npm-cli-issue-5007-repro/node_modules/pgsql-ast-parser/lib' - ... but that path doesn't exist, because
node_modules/pgsql-ast-parseris populated out of thelibfolder, it doesn't contain alibfolder. devandoptionalare true, but both this project's dependency, andpg-mem's dependency, onpgsql-ast-parser, are not dev dependencies and not optional.overridescontains a second entry'pg-mem' => ''... what's that about? (Maybe it does make sense for some internal reason, or maybe it's part of the problem)- and of course,
targetisnull(maybe because of that broken symlink?), whileunsetFlagevidently assumes it can't be null
The package-lock.json file contains:
"node_modules/pg-mem/node_modules/pgsql-ast-parser": {
"resolved": "node_modules/pgsql-ast-parser/lib",
"link": true
},
and if I manually change that "resolved" attribute to replace node_modules/ with ../:
"node_modules/pg-mem/node_modules/pgsql-ast-parser": {
"resolved": "../pgsql-ast-parser/lib",
"link": true
},
then the next npm i invocation completes without (reported errors):
changed 1 package, and audited 245 packages in 1s
8 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
... but it changes the package-lock.json back, undoing my manual change, so if I run npm i again, it fails like before.
Running into this exact issue as well, trying to install Jest.
42 verbose stack TypeError: Cannot set properties of null (setting 'peer')
42 verbose stack at visit (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:104:54)
42 verbose stack at visitNode (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:58:25)
42 verbose stack at next (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:44:19)
42 verbose stack at depth (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\treeverse\lib\depth-descent.js:83:10)
42 verbose stack at depth (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\treeverse\lib\depth.js:27:12)
42 verbose stack at unsetFlag (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:99:5)
42 verbose stack at C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:65:7
42 verbose stack at Map.forEach (<anonymous>)
42 verbose stack at calcDepFlagsStep (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:41:17)
42 verbose stack at visit (C:\Users\<user>\AppData\Roaming\nvm\v16.15.1\node_modules\npm\node_modules\@npmcli\arborist\lib\calc-dep-flags.js:12:20)
Node 16.15.1 (latest LTS at the time of writing) NPM 8.13.2 (latest at the time of writing)
The problem only seems to occur for me in a project with workspaces. Doesn't matter if I execute an install from the main package.json directory, or from any of the individual workspaces. However, MUCH MUCH WORSE is that just executing a straight npm i also breaks with this issue. So installing packages is not only broken for Jest, but is now completely knackered.
This desperately requires a solution.
In a project without workspaces set up, it works fine for me, but I can't just willy-nilly remove the workspaces feature from our projects for obvious reasons.
Edit: same results with NPM 8.11 and 8.10, so this bug has existed for at least a while. This should give it elevated priority to get it fixed, since downgrading NPM is unrealistic.
For me the node where it breaks:
ArboristLink {
name: 'renewi-campaign',
version: '2.0.0',
location: 'node_modules/renewi-campaign',
path: 'C:\\Projects\\Renewi\\src\\VGW.Web\\Frontend\\node_modules\\renewi-campaign',
realpath: 'c:\\Projects\\Renewi\\src\\VGW.Web\\Frontend\\Campaign',
resolved: 'file:../Campaign',
dev: true,
optional: true,
isWorkspace: true,
edgesIn: Set(1) {
{ "" workspace renewi-campaign@file:C:\Projects\Renewi\src\VGW.Web\Frontend\Campaign }
},
target: null
}
- This is a workspace link, as you can see.
pathandrealpathboth exist.- I don't know what causes
devandoptionalto be true. This is a workspace, not a depedency. - And as said before,
targetis null.
I tried to monkey-patch the offending package by inserting various defenses to get node.target to be not null, but it always results in other errors indicating to missing or incorrect values within the target object (I have no way of knowing what it expects of course).
Here's a workaround so that at least we can get back to work. In the arborist package, I've made these changes in the calc-dep-flags.js file:
@@ -30,7 +30,7 @@ const calcDepFlagsStep = (node) => {
resetParents(node, 'optional')
// for links, map their hierarchy appropriately
- if (node.isLink) {
+ if (node.isLink && node.target) {
node.target.dev = node.dev
node.target.optional = node.optional
node.target.devOptional = node.devOptional
@@ -100,11 +100,11 @@ const unsetFlag = (node, flag) => {
tree: node,
visit: node => {
node.extraneous = node[flag] = false
- if (node.isLink) {
+ if (node.isLink && node.target) {
node.target.extraneous = node.target[flag] = false
}
},
- getChildren: node => [...node.target.edgesOut.values()]
+ getChildren: node => [...(node.target?.edgesOut.values() ?? [])]
.filter(edge => edge.to && edge.to[flag] &&
(flag !== 'peer' && edge.type === 'peer' || edge.type === 'prod'))
.map(edge => edge.to),
This makes installs go without errors, but of course I don't know if this is the right way to go. The root cause is the fact that target is null, or the fact that target is assumed (blindly, might I add) to be an object.
running into this again and it's a big problem.
What is the status of implementing a fix?
This bug is even still in triage, so no fix in sight :(
I've been running into this now too.
We also have workspaces (single package-lock.json). This seems to work in linux (WSL more specifically) but not on windows.
I've tested on versions 8.15.0 and 8.11.0, both are broken.
I reinstalled node and still had the same issue. Only once I deleted C:\Users\<user>\AppData\Local\npm-cache was I able to install my packages.
I'm not saying this is the right thing to do, or that anyone should do it. I'm not entirely sure what the side effects might be.
Still the same. A new version has been released since I posted my diff with a fix, and it appears it hasn't been included. The bug still exists.
Let me reiterate how severe this is: we cannot install, update, or uninstall anything. We cannot even do an audit fix which is super important to be able to do!!
This DESPERATELY needs a proper fix.
Who can we tag to escalate this issue to critical/blocking priority?
It seems that a lot of bugs remain in triage for a very long time (up to 10 months as far as I saw) while other issues are removed from triage within hours. Even when we are not in triage anymore I don't think that would guarantee a fast resolution. Especially since there are only a few people affected while millions don't have the bug.
So, I am not sure what the best way is with such a long bug tracker....
My solution is to change my workflow so I don't have to use NPM (or other package managers) anymore for the case in which I triggered the bug. It's even better / faster without NPM, so I'm not sad to have dropped it. It's not something everyone can do, though.
I'd rather not go with a workaround. Besides, the number of people complaining is far smaller than the number of people affected. And if everyone would go with a workaround, NPM would not have any incentive to fix the bug. This would lead to hackery "solutions", like we've already seen way too many of in other fields of tech.
The bug is provable, demonstrable, repeatable, persistent, and totally cripples NPM. It could potentially affect millions of people, because there seem to be several kinds of setups that may be a cause for this bug. I honestly don't see why this isn't enough to get someone to fix it properly, and release it within a week or so. There's no shame in having to perform a hotfix release, but there is definitely a lot more shame in letting crippling bugs linger.
Ran in to this on NPM 8.13.2 after manually editing the package.json to change a remote dependency to use a local version instead (I changed "dep": "1.2.3" to "dep": "file:...") as well as manually bumping a few other package versions, then running npm i. Removing the 3 dependencies that I made local from my package.json manually, then installing them using npm i fixed the issue.
Here's the error log I got:
2022-07-29T14_26_46_259Z-debug-0.log
Seems like the problem is actually in the package-lock.json file - when I revert my changes in package-lock after the first install of the new package, it installs again. I didn't have to remove node_modules.
Seems like the problem is actually in the package-lock.json file - when I revert my changes in package-lock after the first install of the new package, it installs again. I didn't have to remove node_modules.
That's great, but when never having manually edited the package-lock, it should not cause any runtime errors like this. There for I would consider a manual edit of the package-lock to be a workaround, not a solution.
Seems like the problem is actually in the package-lock.json file - when I revert my changes in package-lock after the first install of the new package, it installs again. I didn't have to remove node_modules.
That's great, but when never having manually edited the package-lock, it should not cause any runtime errors like this. There for I would consider a manual edit of the package-lock to be a workaround, not a solution.
Yup I agree with you 100% - just wanted to provide more details in case anyone knew how to fix it
NPM devs - just ran into this again with the latest npm (8.19.2) that comes with Node.js 16.18.0.
Can we please get an explanation of why this isn't bloody fixed yet? This issue BREAKS NPM ENTIRELY in these scenarios, how does that not give this issue highest possible priority?!
Sorry about the tone of voice, but I'm sure you can understand why I'm getting a little bit cross on the appalling amount of progress being made.
Oy! Any and all NPM devs!
Why do you keep releasing new versions of NPM without fixing this issues that COMPLETELY BREAKS NPM.
It's been way too long since this issue got reported, and it hasn't recieved the priority it deserves. Can you tell I'm getting a bit cross? Of course I am. I feel like this issue is getting ignored on purpose.
This issue COMPLETELY AND UTTERLY BREAKS ALL NPM COMMANDS for certain codebases. How does this not get the utmost highest possible priority? Sorry guys/gals, but I would be deeply ashamed for a bug like this, and would probably drop everything and fix this before anything else gets done. I feel this is completely reasonable. Especially after FIVE BLOODY MONTHS of having this BLOCKING issue open without resolution.
But instead, the opposite happens. Explain yourselves please.
While all-caps shouting and “explain yourselves” is a little over the top 😊, the total silence here is discouraging.
I mean literally it is now discouraging me from putting in work to make a useful bug report for the new npm bug I've found, because here I extracted minimal steps to reproduce and summarized the specific things that are going wrong, and ... no response. For half a year. That puts quite the damper on people's drive to help out the project.
I think it's completely justified at this point. This is ridiculous.
first off, i'd like to thank the folks who exercised restraint when expressing their frustration here. i know it's difficult, but your efforts to help us understand this bug as well as the proposed fix above are extremely appreciated.
secondly, i would like to kindly remind folks that we are a very small team responsible for a large number of packages in a rapidly evolving code base. we do our best to triage issues as they come in, but due to the amount of issues we have as well developing new features and processes we often fall behind. while that unfortunately means that some issues do not receive the priority we would like, it does not mean that we are ignoring the issues or the people reporting them.
i'm working on related parts of arborist this week and plan to take a deeper look at this. bear with us a bit longer and we'll get this fixed.
@gthb your reproduction isn't working for me in npm@9, i actually get an unrelated error having to do with resolving the override in your example. i've fixed the unrelated error here and after that i'm still unable to make your reproduction work.
does anyone else have a step-by-step reproduction they can share? i'm not convinced the pull request linked above fixes this issue
@gthb your reproduction isn't working for me in npm@9
I took a look and yep, it reproduces with those instructions up to and including v8.15.1 but not in v8.16.0 onwards. I git-bisected my way to https://github.com/npm/cli/commit/050284d2abb6aa91a0f9ffad5b0c4f074e5dbf6d which is the commit that causes this to no longer reproduce (EDIT: with my particular repro instructions). Before that commit, npm i changes the package-lock.json this way:
--- package-lock-noproblem.json 2022-12-13 22:10:53
+++ package-lock.json 2022-12-13 22:36:34
@@ -1859,6 +1859,10 @@
}
}
},
+ "node_modules/pg-mem/node_modules/pgsql-ast-parser": {
+ "resolved": "node_modules/pgsql-ast-parser/lib",
+ "link": true
+ },
"node_modules/pg-pool": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
@@ -1904,6 +1908,7 @@
"resolved": "../pgsql-ast-parser/lib",
"link": true
},
+ "node_modules/pgsql-ast-parser/lib": {},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@@ -3957,6 +3962,11 @@
"moment": "^2.27.0",
"object-hash": "^2.0.3",
"pgsql-ast-parser": "file:../pgsql-ast-parser/lib"
+ },
+ "dependencies": {
+ "pgsql-ast-parser": {
+ "version": "file:node_modules/pgsql-ast-parser/lib"
+ }
}
},
"pg-pool": {
after which the next npm i will fail as described in the repro instructions.
But it's important to note that once package-lock.json is poisoned in this way, the problem will persist, i.e. newer versions of npm will not fix it. They just won't introduce it in a package-lock.json that doesn't already have the problem. So if I nuke my package-lock.json (or copy the OK version back over it like I did in my bisecting expedition here), then the problem is gone (at least as manifested in my repro case). But versions v8.15.1 and earlier will reintroduce it.
So, others who are still experiencing this in npm versions v8.16.0 and newer (e.g. @thany), do you get it also with a package-lock.json generated from scratch? Or only with one that already has the problem?
Hi @gthb,
Unfortunately I do still have the problem running npm 9.2.0. I recently had to wipe my package-lock (which already had this problem for a long time) and so I got to test out your theory. I deleted my package-lock files (these were at several places in the monorepo - I deleted all of them through a recursive search). I also removed any node_modules folders. Then I went back to the top of the mono repo and ran a fresh install. Then, I ran an install just in the workspace of one package, and was presented with our old familiar error:
npm ERR! Cannot set properties of null (setting 'dev')
I have a totally brand new package-lock that's a whole major version upgraded, so the package-lock very much changed in a significant way, however, I'm still getting the same error.
Let me know if there's any info I can provide to help with diagnosing the issue.
Yeah, to be clear, the particular way to reproduce this that I wrote up above appears to have gone away in v8.16.0. For sure there may be other ways to reproduce it, as the error being reported is quite a low-level internal one. I bet it would be useful to our npm friends (I'm just some passer-by like you) if you could extract a minimal way to reproduce it, from your case, like I did from mine.
Ah I see understood. OK I should have some time to put that together next week. Thanks for clarifying.
This and similar Cannot set property '{something}' of null issues when using workspaces may be fixed by a PR I've just opened: https://github.com/npm/cli/pull/6193
The PR was to fix another specific issue I was having, but the underlying bug it fixes may prevent the package being resolved as null in other places.
@ixalon
Looks like this fix made it into 9.6.0 which I have installed. Still getting the Cannot set properties of null (setting 'peer') error.
Based on the error message, node.target on line 104 of calc-dep-flags.js is null. https://github.com/npm/cli/blob/latest/workspaces/arborist/lib/calc-dep-flags.js#L104
Just for kicks, I kept adding sanity checks until the thing eventually installed.
calc-dep-flags.js line 15
getChildren: (node, tree) => {
if (!tree?.edgesOut) return []; // ADDED
return [...tree.edgesOut.values()].map(edge => edge.to);
}
calc-dep-flags.js line 21
const calcDepFlagsStep = (node) => {
if (!node.target) return; // ADDED
node.js line 1105
matches (node) {
if (!node) return false; // ADDED
diff.js line 74
getChildren: node => {
node = node.target
if (!node) return []; // ADDED
At what cost? Who knows. Everything seems to work ok.
Hopefully this gives you an idea of how this error is propagating through the code.
Just ran into this again today, so am very interested in better diagnostics so I can figure out what is happening.
I'm running npm 9.5.0 in both windows and WSL (Linux) and npm install Express @types/express fails in Windows with the peer message but works in WSL.
@Giwayume - what OS were you using?