The dependency override cleanup problem nobody owns
August 12, 2026 · 6 min read
Every team that has shipped a Node application for more than a year has the same artifact sitting in its package.json: a block of overrides, added under time pressure, that nobody has looked at since.
The story is always roughly this. An audit or a Dependabot alert flags a transitive dependency — something four levels down that you have never imported directly. The direct fix would be upgrading the parent that pulls it in, but the parent has not published a release yet. So you reach for the tool that exists precisely for this moment:
{
"overrides": {
"tough-cookie": "4.1.3"
}
}This is good engineering. The override is the right call: it closes the exposure in minutes instead of waiting on someone else's release cycle. The problem is not that teams add overrides. The problem is what happens next, which is nothing.
The asymmetry
Adding an override has an owner, a trigger, and a deadline. Someone is on the hook for the alert, the alert fires on a schedule, and there is usually a compliance clock attached. Removing one has none of those things.
No tool tells you an override has become unnecessary. Dependabot will not open a “you can delete this now” pull request. npm audit stays quiet, because as far as it is concerned the problem is solved — the override is why it is quiet. The signal that would prompt cleanup is the absence of a signal, and absences do not page anyone.
What it costs you later
A stale override is not inert. It is a pin, and pins push back.
It blocks upgrades that would otherwise be routine. When the parent finally does ship a version with the safe transitive dependency, your override is now pinning that dependency below what the parent wants. Depending on the version you pinned, you get either a resolution conflict or a silent downgrade — a package installed at an older version than anything in your tree actually asked for.
It hides the next vulnerability in the same package. You pinnedtough-cookie at 4.1.3 to escape one advisory. When 4.1.5 lands fixing a different one, your override holds you at 4.1.3. The pin that protected you last year is the reason you are exposed this year.
It makes the file unreadable. After three or four incidents, nobody can tell which entries are load-bearing. New engineers ask about the overrides block and get the same answer every time: “don't touch that, I think it was a CVE.” That answer is how a five-line block becomes a twenty-line one.
Why teams do not just check
The check is not hard in principle. For a given override, you want to know whether the parent dependency now resolves to a version at or above your pin, on its own. In practice, doing it by hand for one entry looks like this:
# Which of my dependencies pulls this in?
npm ls tough-cookie
# What does the newest parent actually resolve to?
npm view request@latest dependencies.tough-cookie
# Is that at or above my pin — and is the advisory range satisfied?
# ...and now repeat for every other override entry.Ten minutes per entry, across a dozen entries, in a dozen repositories, for a task with no deadline attached. That is not a discipline problem. It is a task that costs real time and returns something no one is measuring, which is the definition of work that does not get done.
Making it a routine instead of a project
The fix is not a quarterly cleanup sprint — those get scheduled and then cut. It is attaching the question to something that already happens on its own schedule:
- After a dependency upgrade lands. A parent just moved. That is exactly the event that could have made one of your overrides redundant.
- On the same cadence as your audit. If you already run
npm auditweekly, run the removability check next to it. Same meeting, same owner. - When someone touches the overrides block. Adding entry number nine is a good moment to find out that entries two and five have been dead for a year.
The mechanics matter less than the trigger. What turns override debt around is having any recurring moment where the question gets asked at all — because right now, in most repositories, nothing asks it.
The next post works through the actual decision: when is it safe to delete an npm override?
Backpatch answers this question automatically.
It checks whether the parent dependency already pulls in a safe version, for every override in your package.json, and tells you which ones you can delete. Works as a REST API or an MCP server.