The Most Expensive Thing in Software
I was on a product call with my dev team the other day. We're building an AI-powered chatbot with a UI as good as ChatGPT. And we kept running into this one issue: streaming was buggy. The responses weren't rendering like they should. The markdown wasn't formatting correctly, and the animations were off.
So I started digging through what was happening under the hood. And that's when one of the developers - we'll call him Roeth - said something that made me pause.
"I have never deleted or moved any commented-out code that was created by the previous developer. So the separation will be there. I created my own code. I didn't delete his."
He even said he was going to start adding his author name to new code going forward, so everyone could tell whose work was whose.
I understood exactly what he was doing. He was being professional. Considerate. He didn't want to blow up someone else's work. He didn't want to be blamed if something broke that the previous guy had written. So he wrote around it, on top of it, alongside it - and left the old stuff untouched.
And that's the problem.
The Unwritten Rule That's Rotting Your Codebase
There is an unspoken rule in software contracting: you don't delete another developer's code. You don't touch it. You treat it like a museum exhibit and build your stuff next to it, hoping nobody notices the seams.
It feels respectful. It feels professional. It costs more than you'd expect - and it persists because everyone on the team is doing it for the same polite reason.
What happens: the codebase turns into a junk drawer. You've got Krishna's layer, then Roeth's layer, then whoever comes after Roeth's layer. Each developer is too nervous to remove anything they didn't write, so nothing ever gets removed. The dead code just accumulates. Commented-out functions that haven't run in months, checks written for features that no longer exist, and variables that point to nowhere.
And all of that unused code doesn't just sit there. It causes bugs and confusion, and it caused the exact streaming errors we were dealing with on this call - errors that were being caused, as Roeth noted, by code that was no longer in active use but was still sitting in the application creating interference.
This is what I call the "I Didn't Delete His Code" problem. And if you're building anything with a dev team - agency, SaaS, internal tool, doesn't matter - you need to understand it, because it's probably already happening to you.
How This Shows Up in Products
The product needed to match ChatGPT's presentation layer. Multi-line text input that expands as you type. Proper markdown rendering with bold text and numbered lists. Smooth scroll animations as responses come in, plus mobile and tablet responsiveness at multiple breakpoints. These are table stakes for any modern chat interface.
And we weren't hitting them. The text was getting truncated, line breaks were being removed, and the markdown wasn't rendering. On certain screen sizes, it looked like a completely different product than on desktop.
Why? Because we had two developers' philosophies living in the same codebase without either of them ever being reconciled. Roeth had written his logic. Krishna had written his. Neither had been deleted. So now you've got two different approaches to the same problem, in the same files, and they're fighting each other.
Streaming - the feature where text appears word by word as the AI responds, like you see in ChatGPT - was broken partly because of this. The errors were originating in code that wasn't even actively being used anymore. It was just there. Haunting the application.
Once Roeth started coordinating with the other dev to figure out what needed to stay and what needed to go, things got unstuck.
Free Download: 7-Figure Offer Builder
Drop your email and get instant access.
You're in! Here's your download:
Access Now →The Psychology Behind This (And Why Smart Developers Do It)
I want to be fair here. Developers aren't being lazy or malicious when they preserve dead code. They're being rational given the incentive structure they're operating in.
Think about it from a contractor's perspective. You're brought in to work on a project with no knowledge of the full history or why the previous developer wrote what they wrote. Maybe that commented-out function is commented out for a reason - maybe it's being refactored, maybe it's a fallback for a feature that hasn't launched yet, maybe it's load-bearing in a way that isn't obvious from reading it.
If you delete it and something breaks, you own that. You're the one who deleted code. You get blamed, not the guy who wrote it six months ago. So the rational move, especially as a contractor who's paid per deliverable and needs to protect their reputation, is to leave it alone and write your own stuff.
This calculation comes up on my projects. Any codebase that's had more than one developer on it has this problem to some degree. The question is just how bad it's gotten.
Adding author names to code - which Roeth was planning to do - is a reasonable approach for tracking who wrote what. But it doesn't solve the underlying issue. You can know exactly who wrote every line in the codebase and still have a complete mess if nobody ever audits what needs to be removed.
The First Task on Any Takeover Project Isn't a Feature Sprint
Here's what I'd tell any developer or technical founder taking over an existing codebase from someone else: your first job is to delete.
Before you write a single new line of code, you need to do a deletion audit. Go through what's there and figure out what's active versus what's dead. Create a branch, strip out everything that isn't running, and see what breaks. Git is your safety net - if you delete something you needed, you get it back. Version control exists so you can reverse any deletion in minutes. Use it.
The fear of deletion is irrational in a world where every change is tracked and reversible. You're editing a document with infinite undo. The worst case scenario of deleting something you needed is: you spend an hour figuring out what broke and you restore it. That is a dramatically better outcome than spending weeks debugging phantom errors caused by code that's been dead since the last developer quit.
The conversation my team needed to have - and is now having - was: do we keep these checks or do we delete them? What do we lose if they go? What problem do they cause if they stay? That's the right conversation. It should have happened earlier. It's happening now. And once it's resolved, we can start building the features we need.
How This Applies Even If You're Not Technical
If you're running an agency or a SaaS and you're not the one writing the code, this still affects you. Maybe more than it affects your developers, because you're the one who has to explain to a client or a customer why something that should work doesn't work.
Here's what the non-technical version of this looks like in your business: you hand a project to a new contractor or employee. They don't want to undo or replace what the last person built, even when the last person's work is causing problems. So they bolt their stuff onto the side of it. Now you've got two systems doing the same job. Your onboarding takes longer because new people have to understand both. Your error rate goes up because the systems interfere with each other. Meanwhile, every new feature has to work around the old architecture, and the whole team slows down.
This is a systems problem. And the solution is the same regardless of whether you're talking about code, SOPs, sales processes, or anything else: you need someone with the authority and the mandate to remove things that don't belong anymore.
In my companies, that person is usually me, at least in the early stages. I'm the one who has to say "we're not using that anymore, kill it." Because that call has to come from someone with authority over the product. And if it doesn't get made, the unused code just piles up until the whole thing barely runs.
Need Targeted Leads?
Search unlimited B2B contacts by title, industry, location, and company size. Export to CSV instantly. $149/month, free to try.
Try the Lead Database →The Scope Problem: Why This Gets Worse on Hourly Contracts
One more layer to this. On this same call, we were also dealing with a pricing question - a potential client had asked about an integration, and the team was spending hours figuring out whether to take it on, what to charge, how long it would take.
Stop estimating before you know if you're getting paid. Use a tool - in this case, I said just run it through an AI to get a rough estimate - figure out a number that ensures you don't lose money, and quote that. Don't spend hours going back and forth on scope for a client who hasn't committed anything. That's free consulting, and it slows everything down.
The same logic applies to the deletion problem. Don't spend three days in meetings deciding whether to delete a block of code. Make a decision framework: does this code run in production? If yes, understand it. If no, delete it. Does it have tests? Run them. Does anything break? Fix it or restore it. This should take hours, not weeks.
Both problems - the scope creep and the dead code - persist for the same reason: the team avoids making a unilateral call. The whole team wants consensus. They all want to protect themselves from being wrong. And in that environment, nothing gets fixed.
What Good Dev Handoffs Look Like
If you're managing a technical team, here's what I'd put in place to prevent the "I didn't delete his code" problem from taking root:
- Require a deletion audit as the first deliverable on any takeover. Before any new development starts, the incoming developer documents what's in the codebase, what's active, and what's dead. This becomes a deliverable you pay for and review.
- Use git blame and commit history actively. When you know when something was written and what it was written for, it's much easier to decide if it still belongs.
- Make deletion a celebrated act, not a risky one. In your team culture, removing dead code should be praised the same way adding a feature is praised. Tracking net lines of code deleted tells you the codebase is getting leaner.
- Build in a UI/UX parity review before any feature sprint. This was the other thing we were doing on this call - going through the product screen by screen against a reference standard (in our case, the ChatGPT interface) and documenting every shortfall before starting new work. You don't add new rooms to a house with a cracked foundation.
- Set breakpoint reviews explicitly. Mobile, tablet, desktop - require that every UI change is reviewed at all three. Without an explicit requirement, it's easy to test only the view you're working in.
The Broader Lesson About Courtesy as a Hidden Cost
People are too courteous to cut things that need to be cut. They're too polite to say "this doesn't work, we're removing it." They inherit someone else's decisions and treat them as sacred because it feels disrespectful to undo them.
This is a trap. Not just in software. In business overall.
The previous developer's code isn't a monument. The previous agency's campaign isn't a protected relic. You don't have to work around what the previous employee built. If it's causing problems, remove it. Understand it first - yes. Document what it was doing - sure. But don't leave it there because you don't want to seem like you're disrespecting the person who built it. They're not here. The product is.
The most respectful thing you can do to a codebase - or any system - is to make it work correctly. Sometimes that means being the person who cleans up the mess that accumulated while everyone else was being polite.
Git is your safety net. Use it. Delete with confidence. And the next time a developer tells you "I didn't delete his code, I just wrote mine" - take that as a signal that it's time to sit down and do the audit before you write another line.
If you're building a sales system with the same kind of accumulated bloat - too many tools, too many processes nobody owns, too many campaigns running that nobody's reviewed in months - the same principle applies. Run a deletion audit to figure out what's working and what's dead weight, then build from there.
For the sales side of the house, I put together the Best Lead Strategy Guide which walks through how to think about your outbound stack without layering tool on top of tool until nothing works. Read it if you're in that situation.
And if you want to work through something like this live - whether it's a product problem, a sales system problem, or a team management issue - that's exactly what we do inside Galadon Gold. Live calls where we work through specific problems and walk out with fixes.
Ready to Book More Meetings?
Get the exact scripts, templates, and frameworks Alex uses across all his companies.
You're in! Here's your download:
Access Now →