Ram.Franco LogoRam.Franco
The Bug That Took 3 Days to Fix (It Was a Tab Index)
Debugging

The Bug That Took 3 Days to Fix (It Was a Tab Index)

5 min read

I need to tell you about the form that made me question reality.

šŸŽ­ The Symptom

Simple form. Name, email, date, submit. A golden retriever could build this.

But when you pressed Tab:

  • Name → Submit (what?)
  • Submit → Date (why?)
  • Date → Email (HOW?)
  • Email → the void

Every. Single. Tab. Jumping around like a caffeinated squirrel on a keyboard. šŸæļø

I had explicitly set tabIndex on every input. I had ordered them perfectly. And yet the form was possessed.

šŸ”„ Day 1: "I'm a Professional"

9:00 AM: "This is probably just CSS. Let me check z-index."

11:00 AM: Not CSS. The tab order is genuinely randomizing.

2:00 PM: I've now added tabIndex={1}, tabIndex={2}, tabIndex={3} everywhere. Explicit ordering. Foolproof. Scientific.

3:00 PM: Still broken. Watch in horror as the focus goes 1 → 4 → 2 → 3.

4:00 PM: I start Googling "can browsers be haunted."

5:00 PM: I go home defeated. I dream about forms chasing me through dark hallways. The Tab key is laughing.

šŸ’€ Day 2: "Maybe It's the Browser?"

9:00 AM: Works fine in Firefox. Broken in Chrome. AHA! Browser bug! I'm a GENIUS.

11:00 AM: Wait. It broke in Firefox too now. I don't know what I changed.

2:00 PM: I try:

  • Reinstalling node_modules (the developer's prayer) šŸ™
  • Clearing cache
  • Rebuilding from scratch
  • Asking ChatGPT (it rewrote my entire component)

4:00 PM: The AI-rewritten component has 47 new lines of code and is still broken.

5:00 PM: I contemplate whether I actually know how HTML works.

Did you know? Your brain literally cannot see bugs you've stared at for too long. It auto-corrects. It fills in gaps. You become the bug's accomplice. This is called "inattentional blindness" and it's why fresh eyes matter.

🧪 Day 3: The Scientific Method

9:00 AM: Okay. Time to be a scientist instead of a panicking gremlin.

The method: Remove inputs one by one. Isolate the problem. Find the suspect.

I delete the date field. Tab order is... still broken.

I delete the email field. Still broken.

I delete the phone field. Still broken.

I delete the submit button and—

Wait. The tab order is perfect now. 😳

I look at the submit button code.

<button id={Date.now()} type="submit">
  Submit
</button>

10:30 AM: I stare at id={Date.now()}.

Why. Is. The ID. A timestamp?

I scroll through git blame. Past me wrote this 6 months ago.

Past me was an absolute clown. 🤔

šŸŽÆ The Bug

Date.now() returns a new number every millisecond.

Every single render, the button got a new ID.

The browser's accessibility tree uses IDs to manage focus order. When IDs keep changing between renders, the browser rebuilds the focus tree.

Result: Tab order becomes undefined. Random. Chaotic.

Did you know? Chrome's accessibility engine builds a tree of focusable elements. If element IDs change between renders, the tree gets rebuilt mid-session. This isn't a Chrome bug—it's a "why would anyone do this" bug.

The fix:

<button id="submit-button" type="submit">
  Submit
</button>

Static ID. Three days of suffering → one line change. Works perfectly.

10:35 AM: Three days. One line. One static string.

šŸ” How I Found It

The breakthrough came from going back to basics:

  1. Stop guessing → Start isolating
  2. Remove things until it works → Then add them back one by one
  3. Found the suspect → The submit button was the only element with the bug behavior

The moment I removed the submit button and tabs worked perfectly, I knew where to look.

Sometimes the fancy debugging tools aren't the answer. Sometimes it's just: delete things until something changes.

😭 The Aftermath

I sat in silence for 10 minutes.

I contemplated my life choices.

I updated my LinkedIn to "Former Developer."

(I didn't actually. But I thought about it very seriously.)

šŸŽ“ The Lessons

When you're stuck:

  1. Stop guessing. Start isolating.
  2. Remove things until it works. Then add them back one by one.
  3. Check the boring stuff. IDs, names, typos. The unglamorous suspects.
  4. Past you is a liability. Code review your own old code with deep suspicion.
  5. Take breaks. Fresh eyes on Day 3 solved what tired eyes on Day 1 couldn't.

I have a sticky note on my monitor now:

"Check the IDs, you absolute clown." 🤔

And also:

"Never use Date.now() for element IDs. EVER."

The form works now. The tabs behave. Order has been restored to the universe.

But sometimes, late at night, I still hear the Tab key laughing. šŸŽ¹

Debugging
Career
Humor
Story

More from the Blog

Limited Availability

Ready to Build Something Extraordinary?

Whether you have a fully-defined project scope or just a high-level vision, let's discuss how we can bring it to life with production-grade engineering.

Available for new projects