Many years ago I worked on a program that had a serious problem: the users in one customer’s system were getting deleted periodically. When a user was deleted, any data linked with them was also deleted. We could restore the data from backups, but it was a difficult process, and having a system that loses data wasn’t great for our reputation, so we wanted to resolve it quickly. Our VP of development tried to find the issue first, but after a day without any progress he assigned the issue to me.

I asked some questions and tried my usual tricks. There wasn’t an error message or anything helpful in the logs. There didn’t seem to be any obvious place to start, so I did something crazy: I searched the entire codebase for the world DELETE.

It seemed likely to me that the user was getting deleted by the application, so there had to be a delete statement somewhere that was the cause.

One of the biases I’ve noticed in myself is that I tend to drastically over-estimate the time it will take to perform mundane tasks. In reality, even if there were a few thousand delete statements in the code (and there weren’t), it would still be possible to review them all in an afternoon. Using a good IDE that has a preview for search results and a bit of care with search terms it was possible to get through them even faster.

I found the offending delete statement. The bug was actually a feature!

The customer had re-installed the software at some point and couldn’t find their licence key. The software wouldn’t work without a licence unless it was put into “demonstration mode.” Demonstration mode caused users to be deleted after the trial period ended.

We issued them a new licence key and changed the demonstration mode feature so it wouldn’t be so destructive if it ever got turned on in the future.