AI with AIlabs
← All guides
4 min read

"No Changes Needed" and an Empty Database: What Vibe Coding Actually Looks Like

The gap between code that exists and code that runs, and why the debugging loop isn't you doing it wrong.


Step four of building Briefly Brilliant was syncing users to Supabase the moment they signed in through Clerk. I asked Claude Code to check whether it was already implemented before I built it from scratch.

The answer came back clean: syncUser.ts already existed. The useEffect hook was sitting in the quiz component. The upsert logic was in place. No changes needed.

I signed up with a test account to confirm it worked end to end. Opened the Supabase table.

Empty.

Here's what the next hour actually looked like, because I think the honest version of this is more useful than the summary. I went back and forth between Claude Code and the Supabase dashboard, not in a straight line, in loops. First theory: the sync function wasn't running at all, because test users were hitting a Clerk 404 before they ever reached the quiz page, which is the only place the sync gets triggered. Fixed the redirect config. Signed up again.

Table still empty.

Second theory: something deeper. I dug into the Row Level Security policies and found they were blocking the insert entirely. The code that "existed" and needed "no changes" had never actually written a single row, because a policy several layers away was silently rejecting it.

This is the gap that doesn't get talked about enough. Code that exists is not the same as code that runs. A function can be syntactically correct, sitting in exactly the right file, called at exactly the right moment, and still produce nothing, because the failure isn't in the code you're looking at. It's in a policy, a redirect, a config setting three files away that nobody flagged as related.

I want to be plain about the tone here, because it would be easy to write this as a complaint about AI tools being wrong. That's not what this is. Claude Code was accurate: the sync logic did exist, and no changes to it were needed. The AI tools are genuinely extraordinary at generating and locating code. The real work, the actual debugging, the tracing of why a correct-looking function produces no result, is still real work. It doesn't go away because the code got written faster.

The habit this actually argues for

Verification Prompt
Before confirming a feature is done, don't just report whether the code
exists. Trace it: walk me through what happens when a real user hits this
flow, step by step, including every redirect, auth check, and condition
that has to pass before the code we're checking actually runs.

If you're building with AI and you hit a moment where everything "looks right" and the result is still empty or broken, that's not a sign you're doing it wrong. That's what building actually looks like, with or without AI in the loop. Code that exists is not the same as code that runs. Trace the actual data, not just the code that's supposed to move it.

Get new guides and builds in your inbox

No noise. New artifacts, skills, and lessons when they drop — and early access when agents launch.

next_steps.exe

Want a full structured path instead of one-off guides?

That's Learn AI with AI — a sequenced course that takes you from zero to building real things, with community and accountability built in.

Check out Learn AI with AI →