[BUG] Cannot read properties of null (reading 'resolve')
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.1k
- Forks
- 4.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 19
Description
Is there an existing issue for this?
- I have searched the existing issues
This issue exists in the latest npm version
- I am using the latest npm
Current Behavior
I upgraded my environment to use Node 18.8.0 (from 16.17.0) and I can no longer install a tgz file using npm install:
The error:
Command failed: npm install --no-save mypackage.tgz
npm ERR! Cannot read properties of null (reading 'resolve')
Viewing my npm logs provides the following:
1069 verbose stack TypeError: Cannot read properties of null (reading 'resolve')
1069 verbose stack at [pruneBundledMetadeps] (/Users/danielxu/.nvm/versions/node/v18.8.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:863:38)
1069 verbose stack at [loadBundlesAndUpdateTrees] (/Users/danielxu/.nvm/versions/node/v18.8.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:745:36)
1069 verbose stack at [loadBundlesAndUpdateTrees] (/Users/danielxu/.nvm/versions/node/v18.8.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:760:46)
Near line 863 on reify.js, this is the relevant code snippet:
// create the list of nodes shadowed by children of bundlers
for (const bundles of bundlesByDepth.values()) {
// skip the 'maxBundleDepth' item
if (!Array.isArray(bundles)) {
continue
}
for (const node of bundles) {
for (const name of node.children.keys()) {
const shadow = node.parent.resolve(name) ///////////////////// this line here
if (!shadow) {
continue
}
bundleShadowed.add(shadow)
shadow.extraneous = true
}
}
}
There is a missing null check for when node.parent == null and reading the docs also indicates that node.parent can be null when the node is the top of the tree, e.g. it has no parent. I was able to log the exact node object but it had no parent field:
1060 warn THE NODE IS ArboristNode {
1060 warn THE NODE IS name: 'npm',
1060 warn THE NODE IS version: '5.1.0',
1060 warn THE NODE IS location: '',
1060 warn THE NODE IS path: '/Users/danielxu/.vscode/extensions/myextension/extension/node_modules/npx/node_modules/npm',
1060 warn THE NODE IS isProjectRoot: true,
1060 warn THE NODE IS bundleDependencies: [
1060 warn THE NODE IS 'abbrev',
1060 warn THE NODE IS 'ansi-regex',
1060 warn THE NODE IS 'ansicolors',
1060 warn THE NODE IS 'ansistyles',
... etc (there's 1000 more lines of this object, but with no parent field)
I was able to successfully install my package by modifying reify.js to have a null check:
// create the list of nodes shadowed by children of bundlers
for (const bundles of bundlesByDepth.values()) {
// skip the 'maxBundleDepth' item
if (!Array.isArray(bundles)) {
continue
}
for (const node of bundles) {
if (node.parent === null) continue /////////// this line here
for (const name of node.children.keys()) {
const shadow = node.parent.resolve(name)
if (!shadow) {
continue
}
bundleShadowed.add(shadow)
shadow.extraneous = true
}
}
}
An additional note: When I reverted back to Node 16.17.0 and code traced this file, the function "_pruneBundledMetadeps" is not even called and so never runs into this issue.
Expected Behavior
The tgz package should install normally, just like how it currently does with Node 16.17.0. The code in /Users/danielxu/.nvm/versions/node/v18.8.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js should have a null check for when node.parent is null.
Steps To Reproduce
npm install --no-save mypackage.tgz
Environment
- npm: 8.18.0
- Node.js: 18.8.0
- OS Name: macOS Monterey
- System Model Name: Macbook Pro
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in @npmcli/arborist/lib/arborist/reify.js at _pruneBundledMetadeps, especially the node.parent.resolve(name) call described in the issue. Reproduce with npm install --no-save mypackage.tgz under the reported Node 18.8.0 and npm 8.18.0 environment; done means the tgz package installs normally without the null-property error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nodejs
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100