Case Study: When Vibe Coding Fails

Gemini Generated Image Djwojzdjwojzdjwo

Case Study: When Vibe Coding Fails

· 6 min read
AIWorkflowCase StudyVibe Coding

In my previous post, I explained why vibe coding doesn't work for me. I don't use AI to replace my thinking—I use it to handle execution while I focus on architecture.

This is a case study of what happens when I forget my own advice.

The Setup: I Felt Like Vibe Coding

I wanted to refine the Table of Contents section on my blog. I had a design in my head—something with a timeline, progress tracking, expandable sections. Instead of thinking it through, I opened a chat with a Gemini model and typed this:

"Give me a TOC with a timeline that tracks the article sections. The TOC has an expanded section that will have a flex-1 box following to create an expanded feel. Also add a dash between each L2 headers, a plus if the header section is expanded. The timeline includes a vertical line and a solid dot, the solid dot's position on the timeline correspond to the expanded section's progress."

Let me be transparent: this prompt is absolute nonsense.

I don't even understand it on a second look. What does "a dash between each L2 headers" mean? How does a dot's position "correspond to expanded section's progress"? What is an "expanded feel"?

This is what vibe coders do. We dump half-formed thoughts into a chat window and hope the AI figures out what we meant. Sometimes it works. This time, it spectacularly didn't.

Round One: The Illusion of Progress

The AI produced something that looked right. A timeline appeared. Dots moved. Sections expanded.

So I kept going. More requirements. More vibes:

  • The reading line should track headings
  • There should be three zones—entry, reading, bottom
  • Rubber-band physics for overscroll
  • But only snap back at the top, not the bottom

Each prompt added complexity. Each response looked plausible. But under the hood, the logic was fracturing.

The Wall

I hit it when I tried to explain the overscroll behavior:

  • Top: Stretch up, then snap back with elastic easing
  • Bottom: Stretch down, and stay stretched

The AI couldn't get it. Every model—Gemini, even the expensive ones—kept defaulting to the well-known pattern: rubber-band that always snaps back.

I tried everything:

  • Screenshots
  • Console logs
  • Detailed explanations of my mental model

Nothing worked. Each failed attempt polluted the context. The chat became a graveyard of half-baked implementations.

The AI's Internal Crisis

Here's where it gets absurd.

I looked at the thinking process of the AI agent I was working with. These models have an internal monologue—a "left brain vs right brain" debate before they respond. And I saw this:

"The user must have meant the rubber spacing by 'overscroll'... wait, that's probably not what they mean because they said 'overscroll at the bottom'. I need to clarify what the user means by overscroll."

The AI correctly guessed what I meant. Then it second-guessed itself because my description was so chaotic.

And in its final answer: "This perfectly matches your requirement."

Me, the vibe coder, staring at the screen: "No it doesn't work— wait, YES. I MEANT OVERSCROLL. Exactly as you imagined the first time!"

The AI understood me. Then my own chaos made it doubt itself. And I couldn't even tell it was right because I couldn't articulate what I wanted.

This is the vibe coding trap. You confuse yourself so badly that you can't recognize when the AI gets it right.

The Breaking Point

I finally looked at the code.

It felt like inheriting garbage from a junior dev who quit mid-project. I couldn't trace the logic. I couldn't fix it incrementally. I just wanted to delete everything and start over.

Problem: I hadn't committed anything. Git couldn't help me.

But Cursor could.

Cursor has a feature that lets you rollback the codebase to before the conversation. One click, and my code was clean again.

(Cursor knows vibe coders. It builds for our failures.)

The Cost of Chaos

Here's my Cursor billing after this adventure:

Cursor Cumulative Spend

Every failed prompt. Every "let me try again." Every context-polluting screenshot I uploaded. It adds up.

Vibe coding isn't free. You pay in tokens, time, and sanity.

The Pivot: Two-Stage Approach

Before nuking the chat, I did one thing right.

I asked the AI: "Summarize my chaotic thoughts and format them as a prompt for another agent."

The summary wasn't perfect—it had mistakes—but it was structured. I could see what I actually meant. I could clarify the errors in a few sentences instead of re-explaining everything.

This gave me an idea.

Stage 1: The Architect

New conversation. New agent. One job: understand and design.

I fed it the summary and corrected the mistakes. I didn't ask for code. I asked for:

  • A clear technical specification
  • The three zones defined explicitly
  • The overscroll behavior spelled out in plain logic
  • A prompt I could hand to a builder agent

The context stayed small. No implementation baggage.

Stage 2: The Builder

New conversation. New agent. One job: execute the design.

I started fresh with the specification from Stage 1. Clean context. Clear architecture.

The feature was implemented correctly in three prompts.

What I Learned (Again)

1. Chaos Compounds

Every failed prompt adds noise. The AI pattern-matches on your mistakes. Eventually the context is so polluted that starting over is the only option.

2. You Can Confuse Yourself

The AI understood "overscroll." I didn't recognize it because I couldn't articulate my own vision. Vibe coding makes you a worse communicator, not better.

3. Separate Thinking from Doing

One agent to clarify. Another to execute. The first absorbs your chaos so the second doesn't have to.

4. Summarize Before You Abandon

Even a failed conversation contains signal. Ask for a summary before you close the tab. It might be the seed for your next attempt.

The Result

The Reading Pointer now works exactly as I originally imagined (once I figured out what I imagined):

  • Three zones with distinct scroll behaviors
  • TOC highlighting synced to reading position
  • Smooth animated spacers with CSS transitions
  • Overscroll: elastic at top, sticky at bottom
  • Click-to-scroll positions headings at the reading line
  • Portrait mode optimization (zero processing when TOC isn't visible)

The Takeaway

I said I hate vibe coding. I still do.

But now I have a recovery protocol for when I inevitably fall back into it:

  1. Recognize the wall. If you're on your fifth "let me explain again" prompt, you've hit it.
  2. Extract the signal. Ask for a summary before you abandon the conversation.
  3. Stage 1: Architect. New context. Clarify the design. No code.
  4. Stage 2: Build. New context. Execute the specification. No chaos.

Vibe coding is seductive. It feels fast. But the two-stage approach is actually faster—because you only build once.

Related Articles