Of course, if the total effort of doing the refactor plus building the feature on top of the refactor is less than building the feature on top of the debt, you should always do the refactor first. That's pretty much a no-brainer.
Another idea I've thought about is informally keeping track of possible refactors, maybe give them an informal prioritization, and taking a glance at your list before each task. Maybe there's some value in letting a refactor stew in your brain a little bit before actually putting it in to action. And continually maintaining a rough refactoring plan could help prevent your codebase from entering a state where it's actually unrecoverable.
Of course you could just say “change the process” but it’s also obvious that there are many other factors and pressures that are non trivial
This refactoring could’ve been done ages ago — there’s already some messy and duplicate code there — but now’s the perfect time to do it because 1) I’m already touching and destabilizing that area of the product, and 2) the clearer, de-duplicated code will be easier to spot check.