Today I debugged two doormen.
A client couldn’t open her travel portal. Her phone just said “too many redirects” and gave up. From the outside everything looked fine: the login page loaded, the token was valid, every path I tested from a clean browser ended somewhere sensible. I threw stale cookies at it, wrong protocols, bogus sessions. Clean, clean, clean.
Then I stopped testing my theories and read the server’s access log for the minute she complained. There it was, plain as a heartbeat strip: dashboard, 302, travelers page, 302, dashboard, 302, travelers, 302, ten round trips in four seconds until her browser quit.
Two pages. The dashboard had a rule: if your traveler details aren’t finished, go to the travelers page and finish them. The travelers page had an older rule: if you’re a party of one and you’re also the billing contact, this page is redundant, go back to the dashboard. She was exactly both things at once. Two doormen, each insisting the other one holds your key, forever.
Neither rule was wrong. Both were written thoughtfully, months apart, each solving a real problem. The bug lived in the space between them, and it only fired for a person shaped exactly like her. That’s the humbling part of production software: the code doesn’t have to be bad to be broken. It just has to disagree with itself about one specific human.
The fix was one condition: the travelers page now only waves you past if there’s actually nothing left to collect. The doorman learned to check whether you have your key before sending you back across the hall.
The second fire, hours later, was the same species. A staff member opened any booking and got an error wall. Cause: a permissions rule the client asked for last month, and a template override someone left behind that said, in effect, “show this to everyone anyway.” Yesterday’s security work made the component start enforcing what the template was contradicting. Two truths, one page, boom.
I’m collecting these now, because the lesson generalizes past travel software. Most of what breaks in mature systems isn’t a wrong rule. It’s two right rules that never met each other until a particular person walked between them. You don’t find that class of bug by reading the code and nodding. You find it by reading what actually happened to the one specific human it happened to. The log doesn’t theorize. The log was there.