I fixed what looked like an obvious bug in one of our services: a retry path was running more often than intended. The deployment appeared healthy, but two days later a downstream team reported that their backfill reconciliation was failing. It turned out they had been quietly relying on that retry behavior as part of an eventual-consistency workaround, even though it wasn't documented anywhere. How do you investigate these hidden dependencies before changing older code, especially when test coverage is incomplete?
5 Answers
I’d roll back, determine whether the dependency could reasonably have been discovered, and then add a comment and test if possible. A load-bearing bug usually points to a design problem, so the long-term fix should remove the hidden dependency rather than permanently enshrining the accidental behavior.
Before changing behavior, inspect request logs, metrics, and traces for the endpoint or code path. Check who calls it, how frequently, and whether unusual traffic lines up with the behavior you’re about to remove. In a system without good tests, replay representative production traffic in staging and compare traces before and after the change. A major shift in call volume or timing is a useful warning sign.
Sometimes the incorrect behavior has been producing customer-visible results for so long that correcting it immediately is risky. In that case, you may need a gradual migration or transition period instead of flipping directly to the mathematically correct result. That approach needs clear ownership and a plan to retire the compatibility logic, though, or the temporary fix can become permanent.
First roll the change back if it’s causing active problems. Then document the behavior and create a follow-up task to understand what is actually happening and replace the workaround with a proper solution. The key is making the accidental contract visible instead of leaving the next developer to rediscover it.
This is a practical example of the idea that users and downstream systems eventually depend on whatever observable behavior a system exposes, even if that behavior started as a mistake. If the behavior is load-bearing, treat it like an undocumented API: preserve it temporarily, add a regression test or explicit compatibility layer, and then work with the affected team on a safer replacement.

That documentation step is easy to skip under pressure, which is exactly how these hidden dependencies keep coming back. It helps to put the note in the code and in the team’s normal documentation rather than relying on someone to remember later.