I'm done trying to fix technical debt. When we ask leadership to budget time for fixing tech debt that is holding us back, it's no longer a surprise that the answer is almost always no. Of course they prefer delivering value to users over obsessing about code yet again.
That used to get me mad when I was starting out. How come there was broken code slowing us down, and all leadership cared about was shipping new features! We were losing more time dealing with all the preventable data issues than the time it would have actually taken to fix their underlying cause. That made absolutely no sense!
What I didn't understand at the time was that advocating for technical debt to be prioritised isn't leadership's job: it's ours, as the codebase specialists. Just like when we hire someone to fix our water pipes or car, we're not the ones asking for additional maintenance tasks: that's the specialists' job when they're doing their work and noticing what can be problematic for the future.
Imagine your car mechanic told you that he found a mechanical debt issue that needed to be fixed before it could cause more damage to the car. That would sound like he's scamming you and taking advantage of your lack of car mechanics knowledge to get a higher pay. Imagine you asked him what's the problem exactly, and if we can't just deal with it later, and he'd give you another vague answer, like the problem being missing maintenance, that may cause maintenance-related issues in the future. How happy would you be accepting that extra cost after that interaction?
Don't be that guy.
The problem with technical debt is that it means too many things at once. Critical architecture flaw? Tech debt. Big untested mess full of hard to find bugs? Tech debt. Any code that I think I could have written in a more elegant form? Tech debt.
Technical debt is an almost useless term, and we should abandon it for good.
Instead, we should start describing the actual issues the code faces, and what they mean for the business and for the users. Which happens to be precisely what leadership wants to talk about.
Don't say that we need to tackle technical debt related to deprecated dependencies. That means nothing for the business and for the users. Instead, (depending on your context) you could say that if protecting our users and our operations is a top priority, then we must upgrade any dependency with reported vulnerabilities ASAP, otherwise any attacker can exploit it. And ideally get others up-to-date as well, to minimise development time in case we need to release an urgent update to fix a possible new vulnerability.
Don't say that we have technical debt around data integrity for horizontally scaling the API. Again, there's nothing in there for leadership to feel the need to prioritise it above its own roadmap. Instead, you can say that the API has critical blockers to scaling to meet our projected user activity growth, so the company will miss its growth targets unless this is prioritised and fixed in time.
Notice how neither of those alternatives even mention the term technical debt. And how both mention specific business goals and the real impact on them of not prioritising the work.
It's not leadership's job to advocate for fixing technical debt. It's yours. Leadership's job is to bring actual value to users and stakeholders. And that's what a company is about. So that's the lens us developers also need to use to advocate for this type of work. If the tech debt work doesn't meet that bar, let's be honest with ourselves: maybe there really is more important work to deal with first.
Stop trying to fix technical debt. Start fixing actual business problems, which may incidentally be technical ones.