Four Wrong Theories, Three Sessions, One Bug That Was Actually About My Job Search

Four wrong theories. Three sessions. The better part of a full day. That wasn’t my job search. That was one login bug. But it’s exactly the same shape, and by the end of it, I understood something about theory-chasing that I don’t think I actually knew before this.

The bug

Real-time support ticket app, agent login, working correctly on the first pass. Log in, land on the dashboard, everything fine. Refresh the page, and silently, with no error and nothing to point at, land right back on the login screen. Not every time. Often enough to be a real problem, rare enough to make it genuinely hard to pin down.

Claude walked me through cookies first, four separate ways. Wrong SameSite value. Wrong path. Wrong proxy configuration. Something about how two different localhost ports get treated as two different sites under strict cookie rules. Each theory produced a real fix, worth having, for a real, adjacent problem. None of them touched the actual bug. It kept coming back, patient as ever, waiting for the next session.

After cookies, page-click timing got floated as a theory. Then whether two separate login routes, email/password and Google OAuth, were somehow stepping on each other. Every explanation sounded plausible in the moment. None of them were it.

The instinct that finally spoke up

Somewhere in session three, I got close to giving up on Claude entirely for this one and just trying ChatGPT instead. Not because I thought Claude was fundamentally wrong about React or auth, but because something older and simpler had been sitting quietly the whole time, unused: check the logs. First. Not fourth, after cookies, timing, and login routes had all had their turn. First, the way debugging worked for me fifteen years ago, before any of these specific frameworks existed, when “go read what the server actually says happened” was step one by default, not a last resort you stumble into out of frustration.

Nobody suggested it to me. I remembered it myself, mostly out of irritation at having tried everything else.

What was actually in the logs

Two refresh requests, timestamped to the same millisecond, sitting one line apart:

[refresh] token abc123 rotated -> def456 (12:04:37.418)
[refresh] token abc123 not found, likely already used (12:04:37.421)

Three milliseconds apart. Both requests, same token, nearly simultaneous. The first one succeeded, rotated the refresh token, and set a new cookie. The second one, arriving three milliseconds later, looked for the original token, didn’t find it because it had just been rotated out from under it by its own twin, and responded by deleting the cookie the first request had just set.

The cause of two near-simultaneous requests firing from a single page load turned out to be React’s own StrictMode, a development-only feature whose entire job is intentionally double-firing effects to help developers catch exactly this kind of bug, effects that aren’t safe to run twice. Mine wasn’t safe to run twice, and instead of catching that early and loudly, it quietly created a race condition that looked, from the outside, like nothing more sinister than “sometimes gets logged out for no reason.”

The fix, once the actual cause was visible, was small:

typescript

const hasRun = useRef(false);

useEffect(() => {
  if (hasRun.current) return;
  hasRun.current = true;
  restoreSession();
}, []);

Four lines. A guard so the effect only ever actually runs once, no matter how many times React decides to double-check it in development. Cookies were never broken. Timing was never broken. Two separate login routes were never colliding. The entire bug was one effect running twice and racing against itself.

What that day actually taught me

I’ve been running a version of this same loop for two and a half years now, just against a different kind of log. Not enough certifications, so I earned nine of them. Wrong stack, so I picked up Django, Rails, Elixir, Phoenix, Hono, TypeScript. Resume needs work, so it’s been rewritten more times than I can count at this point. Every one of those theories produced something real and worth having, the same way each wrong cookie theory produced a genuine, legitimate fix along the way.

None of them, so far, has touched whatever the actual cause is.

I don’t know yet what my version of the millisecond collision looks like. I know what chasing the fourth, fifth, and sixth theory in a row feels like, and I know that the thing that actually broke this bug open wasn’t a smarter theory. It was running out of theories, and finally sitting down to read the raw evidence closely enough to see what had been sitting there the entire time, three milliseconds apart, waiting to be noticed.