I was caught out by a hidden API recently. I was rewriting some code that generates some daily caches. I was moving it over to use a newer scheduling framework. Nothing very exciting. The final part of this set of jobs sent summary emails to various inboxes.
However, what I did not consider, is that the owners of these inboxes had configured various rules in their mail clients to sort their incoming mail. I had changed the subject line of the summary emails, and it no longer matched these policies. Once my code was live, the summary emails stopped appearing in the appropriate mail folders. In fact, the change I had made meant that they were now getting sent straight to some recipients’ spam folders!
As soon as I realised what had happened I changed the subject line again. However, I did not know what the email filters actually where. What is worse, most of the email recipients didn’t know what their email filters where either. So I decided to just change the email subject back to what it was before. Unfortunately it took a couple of attempts to get it right! This is because, the old and the new scheduling code where both munging the email subject lines, but not in the same way. Eventually I managed to reverse engineer the old email subject line via the new scheduling framework, and all expected email notifications were restored.
The problem that I had was that the email subject line was an invisible API. I didn’t know about it when I was making my changes, indeed I couldn’t have known about it from the code, but it was there nonetheless.
When I was done, I left a unit-test in place that verified that the email subjects would pass all the appropriate email filters. This will, hopefully, warn any future maintainer not to make any changes to these email subjects!
Part of the lesson here is to always look out for hidden APIs. But more importantly, it is that you won’t see a hidden API until you break it! So don’t create hidden APIs in the first place. And, when you are making changes to your code, always ask yourself, could there be a hidden API here? Finally, hidden APIs are another reason why you should avoid making changes to code that has running in prod for a long time!
Relevant XKCD: https://xkcd.com/1172/
Also an example of Hyrum’s law: https://www.hyrumslaw.com/
With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody.
I had not heard of Hyrum’s law before, that’s very cool.