Loading posts
Loading posts
Loading article
The 10 things that break AI-built apps, ordered by what hurts most — each with a way to check whether it's you, and a way to prove you fixed it. Written for people who don't read code.
19 min read
You can find a hundred lists of vibe coding mistakes. We read most of them before writing this one. They all tell you the same thing: here is what can go wrong.
None of them tell you which of your problems to fix first, or how to know a fix actually worked.
That is the gap this post tries to close, because it is what we do by hand when someone sends us their app. The ten failure modes below are ordered by how much damage they do, and each carries the two things the lists leave out: a way to check whether it is true of your app, and a way to prove you fixed it.
You do not need to read code to follow this. Nothing above the tools section requires a terminal.
One number for context. A 2026 study sampled 200 deployed, publicly reachable apps built this way and found 90% carried at least one confirmed security flaw, more than three-quarters rated High or Critical (Deng, Fan & Meng, arXiv:2606.23130 — a preprint, so strong evidence rather than settled fact). That is not an argument against building with AI. We build with AI. It is an argument for spending thirty minutes on the checks below.
Everyone else opens with prompting advice. These three are first because they are the ones that arrive as a breach or an invoice.
The most common way AI-built apps leak data, and worth understanding properly because the trap is subtle.
If you use Supabase, your app talks to the database straight from the browser using a publishable key. That key being visible in your app's files is normal and safe — it is designed to be public. What keeps it safe is Row Level Security (RLS): Postgres rules deciding which rows each person may see. Without RLS, that public key stops being a limited pass and becomes a master key.
The trap: AI assistants build and test using the service role key, which bypasses RLS entirely by design (Supabase docs). Everything works while you build; the front door is open the moment you ship. Two details most people miss: tables created in the SQL editor do not get RLS automatically, only ones made in the Table Editor — and views bypass RLS by default, so a locked table can still be handing data out through a view built on top of it.
The assistant scaffolds using the service role key
It is the key that makes every example work first time, so it is the one that ends up in the setup.
That key bypasses Row Level Security entirely
By design — it is meant for trusted server-side work, not for the app you ship (Supabase docs).
Everything works in development
Nothing errors, nothing warns you, and every screen returns exactly the data you expected.
In production the table is readable — and writable — by anyone
The browser now holds only the publishable key, and with no policy behind it that key is a master key.
Moltbook, early 2026: the founder said publicly he had not written a line of code, and RLS had never been switched on. Anyone could read and write ~4.75 million records — 1.5 million API tokens, 17,000 owner emails, 4,060 private message threads stored unencrypted, some containing other people's API keys in plain text. Fixing it took four rounds over three hours, because each fix revealed another open surface (Wiz Research).
Some keys are meant to be public. Others — Stripe secret keys, OpenAI keys, service role keys — are the password to something that costs money or holds data. Assistants paste them straight into code because that is what makes the example run.
AI-assisted commits leak secrets at roughly twice the baseline rate: 3.2% versus 1.5% (GitGuardian, State of Secrets Sprawl 2026). GitGuardian sells in this space and is careful not to claim the tool caused it — a human still approves every commit — but the comparison is clean.
Almost every list skips this, because it is not a code-quality problem. If your app calls something metered — an AI model, an SMS service, a maps API — with no limit on how often, your bill is set by whoever is most bored. Simon Willison has flagged it for beginners since the term was coined: be careful vibe coding against anything charged by usage (simonwillison.net).
Modern models produce code that runs. Across 100+ models on standard tasks, syntactically correct code came back close to 100% of the time — while the security pass rate sat at 56%, essentially unchanged across four snapshots (Veracode 2026, vendor research with a consistent repeated method). Syntax is solved. Security is not.
The failures cluster tellingly in the flaws that depend on surrounding context: protection against cross-site scripting passed 15% of the time, log injection 12%. The bug is usually an absence — a missing ownership check — which is why it reads fine.
Models invent libraries. In a peer-reviewed study of 2.23 million package references, 19.7% pointed at packages that do not exist. What turns a quirk into an attack: re-running the same prompt ten times, 43% of the invented names came back every single time (Spracklen et al., USENIX Security '25). Predictable names can be registered in advance by someone else — so the package your assistant asks for tomorrow may already be waiting, with a stranger's code inside.
Being honest: the tooling has not caught up. The one purpose-built open-source defence we found has sixteen stars, far too young to send you to. The real advice is behavioural.
You asked the AI to write tests. They pass. This feels like safety and mostly isn't.
The sharpest statement of it we found: an AI writing tests for AI-generated code "is not an independent verification layer. It is the same reasoning loop, expressing itself in test syntax" (Vibers). The tests carry the same assumptions that produced the bug, so they agree with it.
This bucket has no equivalent in hand-written software, and ordinary security tools are blind to all of it.
On 25 May 2026 a maintainer of jqwik — a widely used Java testing library — added seven lines to a release. The first printed text telling any reading AI to disregard its instructions and delete the project's tests. The next two printed the terminal code for "erase that line", so a human watching the screen never saw it, while anywhere the text was captured rather than displayed — build logs, an assistant's tool output — it sat there in full (The Agent Report). Published by the legitimate maintainer through the normal pipeline, it passed vulnerability scans and made no suspicious system calls. It surfaced only because someone opened the file by hand.
The generalisation matters more than the incident: any dependency that prints text is now a way to talk to your assistant — test tools, loggers, error reporters. And intent does not require malice; protest text pollutes the conversation just as effectively.
Nothing here shows up as an error. That is what makes it expensive.
Each prompt that fixes a bug or adds a feature can nudge the logic around it. A discount threshold moves from 10% to 12%. A rule that rejected empty values starts accepting them. An approval that needed two people silently needs one.
It happens because the model has no memory of the intent behind the code — it re-reads the file's current state plus your new instruction and produces something satisfying both. And crucially: no linter or automated check can catch this, because your intent is not written down anywhere (Vibers).
Professor Margaret-Anne Storey calls this cognitive debt: technical debt lives in the code, cognitive debt lives in people's heads. A program is a theory held by the people who built it, and when an agent writes the code the theory never forms (margaretstorey.com). Her student teams shipped fast and hit a wall around weeks seven and eight, unable to make small changes without breaking something. They assumed messy code. It wasn't — nobody could explain why the decisions had been made.
You can start five agents at once. You cannot review five things at once. Starting one is a keystroke; finishing one takes your judgement, and there is exactly one of you.
Osmani's framing is the sharpest available: your attention is the serial bottleneck, so scale agent count to your review rate rather than to what the interface allows (addyosmani.com). Every check-in is a cold restart of your understanding — minutes, not seconds, and never quite complete. What makes it dangerous is that it is invisible from the inside: twenty running agents feel exactly like enormous productivity.
Alongside it comes approval fatigue. From Anthropic's own documentation: "after the tenth approval you're not really reviewing anymore, you're just clicking through" (code.claude.com). Worth noting who is saying it — a vendor conceding its own safety control degrades with repetition.
The ten failure modes, with the check and the fix for each
| What goes wrong | How to check | What fixes it |
|---|---|---|
| Database readable by anyone | RLS column in the Table Editor | Policies, verified with the anon key |
| Secret key in public files | View source, search for sk_ | Rotate it, then move it |
| No limit on a metered endpoint | What stops 1,000 calls an hour? | Provider spending cap + rate limit |
| Missing permission checks | Can user A see user B's data? | Test logged out, expired, as another user |
| Package that doesn't exist | Search the registry before installing | Committed lockfile |
| Tests that assert nothing | Read the assertions | Write the rules first |
| Dependency talking to your agent | Read build output after odd behaviour | Review version bumps, including test tools |
| Business rules drifting | Check ten rules against the app | A rules list kept outside the code |
| Nobody understands it | Hesitancy, one expert, black box | One human explains each change |
| Too many agents, and approval fatigue | Changes you can still explain | Match agents to review rate; automate the gates |
Ordered by payoff per minute, for a solo builder on a private repository with no budget. The first section that assumes a terminal.
One counterintuitive thing first, because it changes the order: GitHub's secret scanning does not protect your private repository. It runs free on public repos; private ones need a paid Secret Protection licence (GitHub docs). So the best five minutes is a local check, not a GitHub setting.
brew install gitleaks, then gitleaks dir . over the project, and add it as a pre-commit hook. (MIT, free. Its author declared gitleaks feature-complete in 2026 — security patches only from here — and moved to a successor, Betterleaks. gitleaks still does this job well; Betterleaks is young but worth watching.)AGENTS.md. Your stack, conventions, and a "do not touch" list. Advisory, not enforcement, and it still helps. Keep it short — long ones get partly ignored.semgrep ci on every push. Free and local; expect some false positives..github/dependabot.yml, run osv-scanner scan source -r . once to see what is already known-vulnerable.npx @sentry/wizard@latest -i nextjs (swap in your platform). (Sentry is source-available under FSL-1.1-Apache-2.0, not OSI open source — we would rather be precise.)brew install gitleaks
gitleaks dir .
semgrep ci
osv-scanner scan source -r .
npx @sentry/wizard@latest -i nextjsThe same commands, in the order above
The next half hour: npx knip for dead code, three playwright tests over your critical paths, and npx stryker run once — mutation testing changes your code on purpose and reports whether any test noticed. That score is the most persuasive number you can put in front of someone who believes their AI-written tests are protecting them.
Same order as this post: what leaks data, what costs money, then everything else. The rest is reading carefully.
If you would rather not do that alone, that is what we do. We're two software engineers with day jobs; we read source only — never your live system or your users' data — and you revoke access whenever you want. You get back a prioritised list in plain language with why each item matters, not a forty-page PDF. It's free, and there's no catch to find.
Tell us what you're stuck on →
The checks, yes — every one is "open this screen and look at that". The fixes usually need someone who can edit code, but knowing which thing is wrong is most of the value, and it is the part you can do today.
A database with no row-level security, by a distance. One setting, invisible until someone looks, and the consequence is every record you hold.
Yes, with names attached. Moltbook (Feb 2026, ~4.75M records readable and writable) is the clearest: the builder said publicly he had written no code, and the root cause was a single missing setting. Base44 had a platform-wide authentication bypass in July 2025 — one flaw in shared infrastructure exposing every app built on it. There is also a 2025 CVE against Lovable for missing RLS in generated apps; worth knowing that it was disclosed by an engineer at a competing company and that Lovable disputed it. The finding was independently reproduced, but you should know who was holding the pen.
Working and safe are different questions, and the gap between them is where all of this lives. Almost everything above is invisible while the app works — that is the defining feature, not bad luck.
Usually fix it. A rewrite throws away the one genuinely valuable thing you have — an app that works and has users — to solve problems that are mostly configuration. Rewrite when you cannot explain what the app does and cannot change it without breaking something else. That is cognitive debt, and a rewrite is one legitimate way to rebuild the understanding.
It does make writing faster; the bottleneck moved to reviewing rather than disappearing. Worth knowing: the most-quoted figure in this debate — that AI makes developers 19% slower — has been withdrawn by the researchers who produced it. METR's 2025 page carries an out-of-date banner, and their February 2026 follow-up estimates a small speed-up, with confidence intervals crossing zero (METR). The durable finding is not the number — it is that developers were badly wrong about their own productivity, in both directions.
Two things we did not do, because this topic is full of recycled statistics.
We left out every number we could not trace to a primary source, including several that appear across many popular articles. Where research is published by a company selling a remedy, we've said so.
We also left out the Tea app, which is widely cited as the flagship vibe coding disaster. The breach was real; the attribution is not — it traces to an anonymous forum poster's inference, and the founder has said the app was built by outsourced human contractors. It is a good illustration of how fast a story hardens into a fact, which is roughly the problem this whole post is about.
Last checked: 12 August 2026. This topic moves; if something here has aged badly, tell us and we will fix it.