Short answer: The code is rarely the problem. The problems are at the seams — exposed API keys, database rules that let any user read every record, authentication that only hides buttons, and no ceiling on what a bad actor can spend on your AI bill. Audit those five things before you audit anything else.

What is not the problem

Let us dispose of the snobbery first, because it gets in the way of fixing anything.

Code generated with AI assistance is usually clean, conventional and readable. It follows common patterns because it learned from common patterns. In our experience reviewing these projects, the individual functions are frequently better written than the ones in hand-rolled startup codebases of the same age.

The failures are not in the code that was written. They are in the code that was never written, because nobody prompted for it. A model builds what you asked for. It does not ask you what you forgot: rate limits, permissions, audit trails, what happens on failure, who is allowed to see what.

That is a scoping gap, not a quality gap, and it means the fix is targeted rather than total.

1. Exposed keys and secrets

The most common serious finding, and the fastest to check. Open your deployed site, view source, and search the bundle for the strings sk-, api_key, secret and Bearer.

Anything sent to the browser is public. Not obscure — public. An OpenAI or Anthropic key in front-end code can be lifted by anyone who opens developer tools and spent on your account until the card declines.

The fix is architectural but small: any call needing a secret goes through a server function you control, the key lives in server-side environment configuration, and the browser calls your endpoint instead of the vendor's. If a key has ever been in shipped front-end code or committed to a repository, rotate it. Assume it is compromised, because you cannot prove otherwise.

2. Database rules

This is the one that ends companies, and it is invisible during normal use because the app you built only ever requests the right records.

Firebase and Supabase both ship permissive defaults to make getting started easy, and AI-assisted builds frequently never revisit them. The result is rules that allow any signed-in user — or in the worst cases any user at all — to read and write every row in the database. Your customers can read each other's data. Anyone who registers can read all of it.

Check it directly rather than reasoning about it. Sign in as an ordinary test user and try to fetch a record belonging to a different account. If it comes back, you have a breach waiting for its first curious visitor.

The fix is row-level rules that scope every read and write to the owning user or organisation, written deny-by-default, and tested with a second account before launch. This is normally a few days of work and it is the single highest-value thing on this page.

3. Authentication that is only visual

A very common pattern in generated apps: the interface checks whether a user is an admin and hides the admin panel if not. That is a display decision, not a security control. Anyone can call the underlying endpoint directly.

Every rule enforced in the browser must also be enforced on the server. The browser copy is a courtesy to honest users; the server copy is the one that matters. If your app has roles, permissions or paid tiers, verify each one from outside the interface before you launch.

4. Runaway cost exposure

AI features have variable cost per request, which makes them unlike almost anything else in a normal web app. Without controls, one script hitting your endpoint in a loop turns into a four-figure bill overnight.

Before launch you want: per-user rate limits, a hard cap on tokens per request, a global daily ceiling that fails safe rather than continuing to spend, and a billing alert at a number that would worry you. Free-tier abuse is not hypothetical — any public AI endpoint gets found.

The same applies to infrastructure. Serverless platforms bill on invocation, and an accidental recursive trigger — a function whose write fires the function again — is a classic and expensive generated-code bug.

5. The data model

This is the least urgent item and the most expensive to defer, which is a bad combination.

Generated schemas tend to be shaped around the first screen anyone described. They often lack the things you only need later: an organisation or tenant identifier on every record, created and updated timestamps, soft deletes, and a stable identifier that is not the user's email address.

Changing a data model with ten users is an afternoon. Changing it with ten thousand is a migration project with downtime. If you are pre-launch, this is the cheapest it will ever be to fix, so it is worth an hour of scrutiny even though nothing is currently broken.

6. What happens when it breaks

Generated code is optimistic. It handles the path where everything works, because that is the path that was demonstrated.

Ask what the user sees when the AI provider returns a rate-limit error, when a request times out mid-generation, when a payment webhook arrives twice, when someone submits the form twice on a bad connection. In most pre-launch apps we look at, the answer to at least one of those is a blank screen or a silent failure that loses the user's work.

You also want to know that it broke. Error reporting and basic uptime monitoring take under a day to add and are the difference between hearing about an outage from your logs and hearing about it from a customer.

What to keep

Most of it. This is worth saying clearly because the instinct after a scary audit is to start again, and that is usually the wrong call.

You have something most funded startups do not: a working product that real people have used, built quickly enough that you found out whether anyone wanted it before you spent a year on it. The product decisions embedded in it are hard-won and a rewrite discards them along with the bugs.

Keep the product logic, the interface, the flows people already understand and any data you have. Replace the parts listed above. That is a rescue, and it costs a fraction of a rebuild.

Triage order

If you are working through this yourself with limited time, this is the order that minimises risk per hour spent:

  1. Rotate any key that has been in front-end code. Minutes.
  2. Test database rules with a second account. An hour, and it is the one that could end the business.
  3. Verify server-side permission checks. Half a day.
  4. Add rate limits and a billing ceiling. Half a day.
  5. Add error reporting. Half a day.
  6. Review the data model for tenant IDs and timestamps. A day, and much cheaper now than later.
  7. Handle the failure paths. Ongoing, but start with payments and AI calls.

What it costs to fix

Less than people expect, because a rescue is bounded work on a codebase that already functions.

A focused audit and prioritised findings sits at the £495 validation sprint level. Implementing the fixes is typically the £1,995 to £9,000 range depending on how much of the data model has to move. A full production hardening — monitoring, CI, proper environments, load testing — is the from-£28,000 tier, and most pre-launch products do not need it yet.

If you would rather have someone else run the audit, the launch-ready packages are here, or send us the repository and what worries you. Being told which three things matter is often worth more than being told all twenty.

Common questions

Is vibe-coded code bad code?

Usually not, in isolation. AI-generated code tends to be readable and conventional. The problems are almost always at the seams: configuration, permissions, secrets, error handling and cost controls - the parts a prompt did not mention because you did not know to ask.

Do I need to rewrite it?

Rarely. Most rescue work is a security and reliability pass over an app whose product logic is fine. A full rewrite throws away the most valuable thing you have, which is a working product that proved people want it.

What is the single most common critical issue?

Database rules left open. On Firebase and Supabase projects it is common to find rules that allow any authenticated user - or any user at all - to read or write every record. It is invisible in normal use and catastrophic on the day someone looks.

How long does a rescue take?

A focused audit is days, not weeks. Fixing what it finds is typically one to three weeks depending on how much of the data model needs to change. It is almost always cheaper than the rebuild people expect to be quoted.