A fix pull request for a vulnerable dependency usually changes two files: a manifest, which lists the versions your project asks for, and a lockfile, which records the exact versions it actually installs. Sometimes it changes one file, and rarely it touches source code. Knowing which is normal makes review faster.
TL;DR: Expect small edits to a manifest and a lockfile. Be curious if you see many unrelated packages move or if application code changes. A clean diff is short, specific, and matches the explanation.
Definition: A manifest is the file where a project lists the libraries it depends on and the versions it will accept. A lockfile is the file where a tool records the exact versions it installed, so every build gets the same result.
Why do fix pull requests touch files at all?
Think of your project as a recipe. The manifest is the shopping list: "flour, any recent brand." The lockfile is the receipt: "this exact bag of flour, bought on this day." When a flaw is found in one ingredient, the fix has to change the list, the receipt, or both, so that future builds use the repaired ingredient.
Which file changes depends on how your project wrote its original request. If the manifest says "any 2.x version," and the lockfile pins 2.4.1, a fix might only need to change the lockfile to 2.4.2. If the manifest pins an exact version, the fix has to change the manifest too.
What does the manifest do?
The manifest states what your project asks for. Different programming ecosystems name it differently, but the job is the same. A line in it can be loose, such as accepting any version in a range, or strict, such as accepting one version.
A fix pull request edits the manifest when the old request would still allow, or require, the vulnerable version. For example, if your manifest says the project needs exactly 2.4.1, nothing can move forward until that line changes.
Manifest edits are usually small and easy to read. They are also where your intent lives, so reviewers should read them carefully. A tool that changes a loose range into an exact pin, or the other way around, is changing how your project will behave in the future, not only fixing today's flaw. For more on that trade, see dependency pinning versus ranges.
What does the lockfile do?
The lockfile is the receipt. It names every package your project installs, including packages that your packages depend on. Tools use it to make builds repeatable. If you do not have one yet, read what is a lockfile.
The npm documentation describes why this matters in automated builds. The command npm ci is meant for automated environments such as test platforms and continuous integration. It requires an existing lockfile, and if the dependencies in the lockfile do not match those in the manifest, npm ci exits with an error instead of updating the lockfile. It also never writes to the manifest or lockfile, so installs are essentially frozen.
That behavior is helpful for a fix pull request. If the two files in the change disagree, the build fails loudly, and the problem is found before merge instead of after.
Which files does each kind of fix change?
| Kind of fix | Files usually changed | What a healthy diff looks like |
|---|---|---|
| Patch update of a direct dependency | Manifest and lockfile | One version number changes in each |
| Patch update when the manifest uses a range | Lockfile only | One package version moves in the lockfile |
| Update of a transitive dependency | Lockfile, sometimes manifest | The target package moves, perhaps with its parent |
| Major version upgrade | Manifest, lockfile, often source code | Many lines, and possibly code edits to match new behavior |
| License fix | Manifest, lockfile, sometimes a notice file | A swap or removal of one package |
| Configuration fix | A settings file or a build file | A small, targeted edit |
A direct dependency is a library your project names itself. A transitive dependency is a library that one of your libraries pulls in. If the distinction is new, read direct versus transitive dependencies, and see how to fix a vulnerable transitive dependency in npm for the steps.
What does a healthy diff look like?
A diff is the red and green view that shows removed and added lines. This invented example shows a healthy fix.
manifest:
- pretty-dates: 2.4.1
+ pretty-dates: 2.4.2
lockfile:
- pretty-dates 2.4.1
+ pretty-dates 2.4.2
Two files, two lines each. The explanation says "update pretty-dates to repair a crash bug," and the diff does exactly that. This is the easy case.
What should make you slow down?
Here are patterns that deserve a second look.
- Application code changed. A fix pull request that edits your own source files is doing more than a version bump. That can be legitimate for a major upgrade, but ask why.
- Many unrelated packages moved. A lockfile that rewrites dozens of entries may mean the tool regenerated the whole file, which can bring in changes you did not intend.
- The manifest changed in a surprising way. Loosening or tightening a version request is a policy decision.
- A new package appeared. A fix should not usually add a brand new dependency. If it does, check what it is and who maintains it.
- A file you do not recognize changed. Check what it is for before approving.
What does a worked example look like?
This example uses invented names and numbers to show how to count the size of a change.
Worked example (invented numbers): A project has a manifest with 25 lines of dependencies and a lockfile with 900 lines. Two fix pull requests arrive in the same week.
| Pull request A | Pull request B | |
|---|---|---|
| Title | Fix pretty-dates denial of service | Fix many vulnerabilities |
| Version jump | 2.4.1 to 2.4.2 (patch) | 2.4.1 to 3.0.0 (major) |
| Manifest lines changed | 1 | 6 |
| Lockfile lines changed | 2 | 214 |
| Source files changed | 0 | 9 |
| Tests passing | 300 of 300 | 281 of 300 |
| Review time (invented) | 10 minutes | 2 hours, then closed |
Pull request A is the textbook small fix. You read two files, the tests pass, and you approve.
Pull request B changes 214 lockfile lines and 9 source files, and 19 tests fail. That does not mean the tool made an error. It means a major version upgrade needs a developer to adapt the code. The right move is to close the pull request, make a planned upgrade task, and apply a smaller fix in the meantime if one exists. Seeing the size of the diff gave you that decision in minutes, before any code merged.
Why does the explanation matter as much as the diff?
A reviewer needs to compare two things: what the pull request says it does, and what it actually does. When these match, trust grows. When they differ, something is off. A good pull request names the package, the old and new versions, and the files expected to change. For more on how supporting evidence can travel with a change, read evidence attached fix PRs and why reviewers trust them.
How does Safeguard fit in?
Safeguard provides autonomous remediation with fix pull requests as a generally available capability. It analyzes a vulnerability, proposes a solution, assesses the impact, opens the pull request, and validates it, and it includes breaking change detection. Fix pull requests are off by default, and every category is set to Manual, so nothing opens until your team turns it on.
Its SBOM and dependency scanning show what your project contains, including transitive dependencies, so you can see which file a fix is likely to touch. The Safeguard CLI can also write code, in addition to scanning. For a quick look at your own project, use the free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at which version the fix picks and how small the change is compared with the whole project.
Quick check
Why does a fix change both a manifest and a lockfile?
The manifest says which versions your project accepts, and the lockfile records what it installs. If the old request still allows or requires the vulnerable version, both need to change so that builds use the repaired one.
Is it a problem if only the lockfile changed?
Not usually. If the manifest uses a range that already allows the fixed version, only the lockfile needs to move. Check that the target package and version match the explanation.
What does npm ci do if the two files disagree?
According to the npm documentation, it exits with an error instead of updating the lockfile. That makes mismatches visible in automated builds.
Should a fix pull request ever change my own source code?
Sometimes, mostly for major upgrades. When it does, review it more slowly and make sure your tests cover the affected code.
Sources
- npm ci, npm Docs, on clean installs, lockfiles, and mismatches.
- Semantic Versioning 2.0.0, on patch, minor, and major version meanings.
Last reviewed: 19 October 2026.