EngineeringVibe codingResearch
Write-only codebases: we keep adding code and nobody cleans up
Refactoring of year-old code is down 74%, duplication up 81%. A fresh copy from an agent is faster than reading the old one, and we pay for it later in bug fixing.

Most teams are now running write-only codebases and don't realize it. There's an old joke that Perl is a write-only language, easy to write but close to impossible to read later, and I think the joke now fits whole codebases, whatever the language. We are adding code faster than ever, which on its own is fine, but almost nobody goes back to look at the old code once it's there.
This is not just a feeling, there are numbers behind it. LeadDev reported on research by GitClear and GitKraken that analyzed 623 million real-world code changes from 2023 to 2026, and in that data AI-assisted commits now make up a quarter of all commits. Four of the findings matter here.
Duplication, which they count as five or more consecutive repeated meaningful lines, is up 81% compared with pre-AI times. "Move", a measure of how often commits edit existing code, is down 70%, and the article reads that as a sign that code reuse is declining. Legacy refactoring, i.e. changes to code that was last touched more than 12 months ago, has fallen 74% since 2023. Error masking is up 47% in 2026 relative to the base year, where GitClear measures it as the density of catch blocks, safe-navigation operators and stubbed methods that quietly swallow unexpected input.
Put those four together and you get a team that keeps building new code on top and never cleans up the old.
Why the new copy keeps winning
Yes, I understand the pull, I feel it myself. Say you need to parse a date or retry a flaky API call, and you're fairly sure the repo already has a function that does exactly that. Finding it means searching, reading code someone wrote two years ago, working out its edge cases and deciding whether it really fits. Asking an agent for a fresh one takes about a minute, and the fresh one passes its tests.
Each of those choices is reasonable on its own, but the problem shows up in the total. You end up with three versions of the same rule, each slightly different, and when someone fixes a bug in one of them the other two quietly keep it. After a while nobody knows which version is the real one, so the next person, reasonably enough, writes a fourth.
The error masking number worries me more than the duplication. A catch-all that logs something and carries on makes the symptom go away, but it also hides the cause. That is usually how a small fault turns into a long afternoon of debugging a year later, when nobody remembers why the catch is there.
The awkward part is that none of this looks bad from the outside. Addy Osmani calls it comprehension debt, the growing gap between how much code exists in a system and how much of it any human genuinely understands, and his point is that our usual measures can't see it. As he puts it, "Velocity metrics look immaculate. DORA metrics hold steady."
That matches how I think about metrics in general. We measure what is easy to count (commits, pull requests, deploys, lead time), and understanding is not easy to count, so it slowly drops out of the conversation. A team can look faster every quarter while the share of the codebase anyone could actually explain in a review keeps getting smaller.
Where the bill ends up
Debt gets paid eventually, and with code it is mostly paid as bug fixing. In Anthropic's Economic Index report, the most prevalent task on Claude.ai in November 2025 was modifying software to correct errors, which came to 6% of usage on its own. The same report says Claude assessed personal tasks as successfully completed 78% of the time, compared with 61% for software development.
Let's not read more into that than is there. The report doesn't say duplicated code causes those bugs, and it doesn't measure codebases at all. What it does show is that a lot of the work goes into fixing code that already exists, and fixing is the job that depends most on someone understanding what they're looking at.
None of this needs a big programme. In my experience a few small habits go a long way, and the first is delete-first pull requests. Before you add a helper, look for the ones it would replace and remove them in the same change. A PR that adds 40 lines and deletes 120 is a good PR.
The second is to make the agent search before it writes. Tell it every time to find existing code that does the job and reuse or extend it, and to explain itself if it decides not to. Agents are good at searching a repo, but in my experience they often skip that step unless you ask.
The third is a regular refactor slot. Put time on the calendar for code nobody has touched in a year, because if it never gets scheduled it never happens, and that 74% is roughly what never happening looks like.
The fourth is to treat a catch-all as a question. When a review shows an error being swallowed, ask what the error actually was. If nobody can tell you, that's the bug.
Somebody will maintain this code in two years. It might be a new hire or an agent, but quite often it will be you, wondering which of the three date parsers is the one that works. That's one of the reasons we build Workbricks around reusable blocks, so the second app reuses the first one's pieces instead of copying them.
Code nobody understands is not an asset, it's a cost.


