npm / npm/cli

[BUG] Cannot read properties of null (reading 'resolve')

Open
#5,439 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Needs Triage Release 8.x
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.