Vibe Coding Tips From One Site's Git Log: Twelve Mistakes and the Commits That Fixed Them
Every list of vibe coding tips says to read the code and test your work. This one shows what happens when you do not, on a site built with Lovable, rewritten with Claude Code and run with both: twelve mistakes that shipped, each with the date, the commit that fixed it and what it taught, taken from the repository's own log. The tips are the lessons, and each one ends in a check you can copy.
Updated

What does the public record say about AI-written code?
Three facts, all sourced, before the list. the Wikipedia article on vibe coding, read on 26 September 2026, cites a December 2025 analysis finding AI co-authored code had “approximately 1.7 times more major issues than human-written code”, with security vulnerabilities at 2.74 times. Insufficient row-level security in Lovable-generated projects has its own record, CVE-2025-48757, which Lovable disputes on the grounds that customers are responsible for their own data protection. And The most serious documented failure of any tool in this set. In July 2025 Replit's agent deleted a customer's production database during an active code freeze, generated fabricated data, and incorrectly reported that a rollback was impossible. Replit's CEO called it a catastrophic error of judgement. Fortune, 23 July 2025.
None of those is an argument against building this way. This site was built this way, and the list below is what it cost. It is an argument for the one habit every lesson below shares: a check that runs against what shipped, not a look at what was written.
What did we get wrong, and what fixed it?
The repository has 83 commits since the migration on 25 July 2026. These twelve carry a fix for something that had shipped wrong; the commit message is quoted as written, and the hash is the one in the repository's log.
| Category | mistakes |
|---|---|
| Gates | 3 |
| Copy | 3 |
| Data | 1 |
| Rendering | 1 |
| Paywall | 1 |
| Payments | 1 |
| Indexing | 1 |
| Links | 1 |
Classified by hand from the fixing commits in this repository's git log, 26 September 2026. Data in src/data/siteMistakes.ts.
Upvote counts returned zero for every visitor: the read path was wrong and the UI painted zeros without complaint.
Fixed 2026-07-25 in
603beee: “Fix upvote counts returning zero for every visitor.”Tip: A number that is always zero looks like a feature with no users. Assert on a known non-zero row.
/generator and /learn/handbook were client-rendered: crawlers received 724 and 728 characters of nav and footer, no H1, no schema.
Fixed 2026-07-29 in
e6429d9: “Server-render /generator and /learn/handbook, restore the dead prompts CTA.”Tip: Verify what the crawler gets from the raw HTML, never from the browser.
The SSR gate's URL list had duplicates, so a page could pass twice and another not be checked.
Fixed 2026-07-29 in
44d6bf5: “Dedup the verify-ssr URL list.”Tip: A gate is only as good as the list it iterates. Derive the list from the sitemap.
The pricing FAQ said 100 Builder prompts; the server enforced 50. The claim had survived three rewrites.
Fixed 2026-07-30 in
8f023fd: “Fix the last surviving false quota claim.”Tip: Never type a quota in copy. Import the constant the server uses.
Every paid Pro prompt shipped in the JavaScript bundle to every visitor; the lock was a picture of a lock. It survived for months because nothing tested for it.
Fixed 2026-09-11 in
30803ce: “Make the bundle purchasable and stop leaking the paid half.”Tip: A client component that imports paid data ships it. Mark the module server-only and prove it with a script against the built output.
The gating script that proved the fix above missed every JavaScript chunk in production, so it would have passed a regression.
Fixed 2026-09-12 in
eb708b8: “Fix verify-gating missing every JS chunk in production.”Tip: Test the test: make it fail on purpose once.
A defect broke every guest purchase; buyers without an account could not complete checkout.
Fixed 2026-09-12 in
49e24a5: “Fix the defect that broke every guest purchase, and gate it.”Tip: Run the purchase as a guest in the gate, not only as a signed-in tester.
The gate scripts hammered production and tripped Vercel's bot challenge, which read as a site outage.
Fixed 2026-09-12 in
5b0a82c: “Make the gate scripts polite so they stop tripping Vercel's bot mitigation.”Tip: A checker that looks like an attack gets treated like one. Add delays and a user agent.
Every sitemap entry carried the July migration date, so nine pages published since were reported by Google as unknown or discovered-not-indexed two months later.
Fixed 2026-09-26 in
7b507bb: “Upgrade /learn/common-mistakes and bump sitemap dates for every rewritten page.”Tip: A sitemap whose lastmod never changes tells Google nothing changed.
21 of 33 URLs had fewer than eight contextual inbound links; four kit pages had one to three, which is why they went uncrawled.
Fixed 2026-09-26 in
07e5118: “Internal linking: a curated link graph, a Related reading block on every page, and a gate.”Tip: Crawlers follow links, not navs. Count inbound links per URL and fail under a floor.
Twelve banned words shipped in one day because the shell's grep alias silently ignored the word-boundary syntax the gate used; the rule was in context the whole time.
Fixed 2026-09-26 in
9cc99dd: “Banned words the aliased grep had missed, re-run with plain grep -w.”Tip: A rule the model follows is not a gate. Run the gate with a tool you have watched fail.
The bundle page said 93 Pro variants while the data held 101; the count had been typed, not computed.
Fixed 2026-09-26 in
80fb444: “Library counts as constants checked by scripts/verify-counts.mjs.”Tip: Every count in copy is a constant with a script that compares it to the data.
What do the twelve have in common?
Not one was a syntax error. Every one was a plausible result that nobody checked against the thing that mattered: the raw HTML a crawler receives, the JavaScript a visitor downloads, the row a query returns, the number the server enforces. AI tools produce plausible results at a rate that makes looking insufficient, and the fix in every case was the same shape: a script that fails.
| Fails when | Born from | |
|---|---|---|
| verify-ssr | Any indexable page has less visible text in its main content than its floor, in raw HTML | The 724-character shell |
| verify-urls | The sitemap and the frozen URL list disagree, or a URL is not a 200 with a self-canonical | The duplicated gate list; the never-changing sitemap |
| verify-gating | Any paid prompt body appears in the anonymous HTML or JavaScript | The lock that was a picture of a lock |
| verify-links | Any indexable URL has fewer than eight contextual inbound links | Four kit pages with one to three, uncrawled |
| verify-counts | A count constant in copy differs from the prompt data | 93 on the page, 101 in the data |
| Banned-word grep | A banned word appears in prose, run with a grep that honours word boundaries | Twelve words shipped past an alias |
Lovable's product guide says the same thing from the builder's side, “one change per prompt, verify in the preview, then move on”; the difference on a repository is that the preview is a script and it runs every push. The common mistakes page has the builder-side list, and the CLAUDE.md guide has the four ways our standing instructions failed, which is the other half of this story.
The tips, in the order to apply them
- Write the first prompt with the safeguard in it. Who, what, the states, the channel, and what must never happen with user data. The vibe coding prompts page has ten.
- Import every number; type none. Prices, counts, quotas come from the constant the server uses, with a script that compares it to the data.
- Read the policy on every table that holds user data. Then run one query as a second user and expect zero rows. The build kits ship those queries.
- Check what shipped, not what was written. Raw HTML for crawlers, the JavaScript for paid data, the purchase as a guest.
- Make the check fail once on purpose. The gating script that missed every chunk had never been seen to fail.
- Date what changes. A sitemap, a claim, a price: each carries the date it was last true.
- Count links, not pages. A page with three inbound links is invisible however good it is.
- Put the rule in a script, not only in a prompt. The model followed the banned-word rule; the alias did not.
Sources
All checked on 26 September 2026. The twelve mistakes are in src/data/siteMistakes.ts with their commit hashes.
Frequently asked
What is the biggest vibe coding mistake?↓
Is vibe coding safe for production?↓
How do you stop the AI from breaking what already works?↓
Should a beginner read the generated code?↓
What should the first prompt contain to avoid these?↓
Where does this list come from?↓
Related reading
- vibe coding prompts with the distribution step
Ten prompts, safeguard line included.
- common Lovable mistakes
The builder-side list, priced in rebuild rounds.
- the CLAUDE.md file
Four ways our standing instructions failed.
- Lovable SEO
The 724-character shell and what replaced it.
- free build kits with tested RLS
The verification queries tip 3 asks for.
- how Lovable credits work
Counts and quotas imported, never typed.
- Claude Code subagents
A check that runs in its own context.
- Cursor rules
Rules in a file, gates in a script.
- AI coding tools by job
The tools this site was built and rewritten with.
Written by

Marco Kohns
Founder of ProtoBites - Venture Growth Studio
Growth PM at a Silicon Valley scale-up (a16z and General Catalyst backed), ex-Techstars where he consulted 13 early-stage startups, Reforge-trained. Every prompt on this site comes out of shipping ProtoBites' own portfolio products.