We Fixed The Bug. It Wasn't The Bug.
A locked-out customer got a same-day fix for three genuine bugs in a device-verification system. The fix was correct and still wasn't the cause: a live probe run after shipping found two active, unchallenged devices and an expired trial instead. Reasoning from code and a well-fitting timeline produces a confident story, not evidence.
The diagnosis you’re quietly proud of
Somewhere in your ticket queue is a bug you solved without looking at the thing that actually broke.
The code explained the symptom. The dates lined up. Nobody checked it against reality before it shipped, because checking felt unnecessary once the story fit that well.
You have one of these right now. Ours got written up as fact, fixed within a day, and was still wrong.
The theory that fit too well
A customer told us he’d been locked out of his account for a week. Someone had a theory inside the hour: he’d started on one login client and switched to another, and the switch had broken a device-verification check that only worked for the client he’d left.
The theory held up under code review. The verification step pulled an email address off the login token. One client always sent it. The other never did. Switch clients, lose the address, and the retry code meant to email a fresh access code has nowhere to send it.
Worse, the same misreading had disabled the two tools he’d need to tell us he was stuck once his account lapsed. That explained why we heard about this a week late, from a person, rather than the moment it happened.
None of that is a stretch. Those were three real bugs, in a real system, that any customer with the wrong client history could still hit. They got fixed, tested, and shipped inside a day, because they deserved to be.
They just weren’t what happened to him.
The probe that told us we were wrong
There was a reason nobody checked the theory against his actual account first: nobody could. The database holding his real device history sat behind a production wall, and the sensible, correct permission gate in front of it did its job. So the write-up went out as an answer without a look, because the code explained it and the timeline agreed, and a story that ties together that neatly starts to feel like proof.
We built a small tool anyway. Not because the write-up looked shaky. Because “we can’t check this directly” is a reason to build the missing tool, not a reason to skip the checking.
Ran it against his account the moment it deployed.
Two devices. Both active. Neither had ever been challenged. Two of a limit of five.
Nothing in the device gate had fired against him. Not once.
What had actually happened, and how little of a story it was
His last successful call landed six hours before his trial expired. His trial expired on schedule. He hadn’t connected since.
He wasn’t locked out by anything we built. He’d hit the ordinary end of a free trial and needed to click through the same reconnect flow as anyone else whose trial has ever run out.
The elaborate diagnosis was more interesting than the true one. That is usually the tell, not the reassurance.
The habit worth stealing
When you can’t see the live state directly, whatever you write about it is inference, however carefully you argue it. Code that explains the symptom and a timeline that agrees with it feel exactly like evidence. They are not. They are a hypothesis that hasn’t been checked yet, and the ones that fit beautifully are the ones you’re least likely to go back and check.
The fix isn’t reasoning more carefully. The reasoning was fine, which is why the write-up read so convincingly.
The fix is smaller and more mechanical: before you tell anyone a diagnosis is the cause, build or find the one tool that lets you look at the real thing, and use it, even when the story you already have is good enough to stop at. If looking is blocked, that block is the finding, not an excuse to publish anyway.
We shipped a wrong diagnosis as a confident, specific write-up, and it happened to also describe three real bugs worth fixing on their own terms. That second part is the trap. A theory that turns out partly true is still a theory, right up until something that actually reads the state agrees with it.