npm / npm/cli

[BUG] Incorrect (previous) version number persists in package-lock.json after removal from package.json

Open
#8,831 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Needs Triage
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

If there is a pre-existing package-lock.json that has a defined package version number, and package.json is updated to remove the version number, then running npm install does not result in the version number being removed from package-lock.json. package-lock.json incorrectly retains the old package version number.

Expected Behavior
  • If the version number is removed from package.json, then after running npm install, the version number should be removed from the package in package-lock.json.
  • Considering the case of a package with no dependencies and no version number, the package-lock.json generated from the starting point of no package-lock.json should be the same as the package-lock.json generated when a package with version number and no dependencies has its version number removed.
Steps To Reproduce

Create a package.json with no version and no dependencies

{
  "name": "test-package",
  "private": true,
  "description": "A test package",
  "license": "UNLICENSED",
  "author": "test author"
}

Install it.

npm install --package-lock-only

This produces a package-lock.json with no version number, as expected:

{
  "name": "test-package",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "test-package",
      "license": "UNLICENSED"
    }
  }
}

Update package.json to include a version number:

{
  "name": "test-package",
  "version": "1.0.0",
  "private": true,
  "description": "A test package",
  "license": "UNLICENSED",
  "author": "test author"
}

Install it.

npm install --package-lock-only

This produces a package-lock.json with version number, as expected:

{
  "name": "test-package",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "test-package",
      "version": "1.0.0",
      "license": "UNLICENSED"
    }
  }
}

Now update the package version number in package.json. The new package.json is:

{
  "name": "test-package",
  "version": "1.0.1",
  "private": true,
  "description": "A test package",
  "license": "UNLICENSED",
  "author": "test author"
}

Update package-lock.json to reflect the change:

npm install --package-lock-only

The package-lock.json file is updated to have the new version number, as expected:

{
  "name": "test-package",
  "version": "1.0.1",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "test-package",
      "version": "1.0.1",
      "license": "UNLICENSED"
    }
  }
}

Now decide to go back to a versionless package, removing the version from package.json. Update (Revert) package.json to:

{
  "name": "test-package",
  "private": true,
  "description": "A test package",
  "license": "UNLICENSED",
  "author": "test author"
}

Update package-lock.json to reflect the change:

npm install --package-lock-only

At this point, package-lock.json should be updated to have the version number removed, and so look like this (just like it did when it was first installed with no version number specified and no package-lock.json present):

{
  "name": "test-package",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "test-package",
      "license": "UNLICENSED"
    }
  }
}

However, the actual contents of package-lock.json are:

{
  "name": "test-package",
  "version": "1.0.1",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "test-package",
      "license": "UNLICENSED"
    }
  }
}

The version number is still present, despite having been removed from package.json.

Environment
  • npm: 11.6.4
  • Node.js: 11.6.4
  • OS Name: Ubuntu 24.04.3 LTS
  • System Model Name: Irrelevant I think (VM)
  • npm config:
; node bin location = /usr/local/bin/node
; node version = v24.11.1
; npm local prefix = /home/some-user
; npm version = 11.6.4
; cwd = /home/some-user
; HOME = /home/some-user
; Run `npm config ls -l` to show all defaults.

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 by reproducing the version-removal sequence with package.json, package-lock.json, and npm install --package-lock-only. Trace the package metadata and lockfile generation path responsible for the root package version. Done means removing version from package.json removes both stale version fields from package-lock.json and preserves the expected output for the shown cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.