Reusability has costs. We often ignore those costs. One cost is coupling.
"Make Your Code Reusable"
"Make your code reusable." - This sounds great.
"Couple your code to other places in the codebase." - This sounds bad.
At least in part, they mean the same thing -- reused and coupled. But often we say that we should do the first and avoid the last. And we don't sense the contradiction in the advice. We know there is a cost to coupling. We just don't remember to think about it when we start praising and encouring reusability.
No Solutions, Just Tradeoffs
In other words, no solution is without tradeoffs.
Reusability comes with coupling. That means it's not immediately virtuous to be reusable. It has to be worth it for the cost incurred. Coupling is one cost.
As a single cost scenario amongst several: You write a function that does a thing. You have two callers from two separate clients use it. Today their needs are exactly the same, hence the reuse. But tomorrow, the callers' needs diverge: caller 2 has a new need. Now your reused function must support caller 2 and not break caller 1. But you weren't working on caller 1. But you've coupled the destiny of your reused function, caller 1 and caller 2. How will you pay the price?
Not a Default
Feeling like your reusable code is paying off is a great feeling. But I don't think it's a good default goal. We're shouldn't seek it always or want it immediately. We should weigh our options and sometimes couple and sometimes not.
In fact, I think a better a better default stance is the opposite of reusable: by default, to make our code as local as possible.