Skip to content
NEXDGE
Start free

What is vibe coding, and why does the code break in production?

Vibe coding lets anyone build software by describing it to an AI. The code works in the demo and fails in production, in four predictable ways.

7 min readUpdated 29 July 2026
In short

Vibe coding is building software by describing what you want to an AI and shipping what it writes. It fails in production because language models are trained on code that demonstrates a concept, not code that survives real users, real load, and real attackers.

Key takeaways
  • Vibe coding means describing software to an AI and shipping what it produces, rather than writing it line by line.
  • AI-generated code fails differently from human code: the surrounding file is usually excellent, which hides the one line that is wrong.
  • The four recurring failure classes are silent error handling, broken authorisation, business-logic drift, and N+1 database queries.
  • None of these appear in normal testing, because normal testing exercises the happy path and these only fire on the adversarial or high-load path.
  • The fix is not to stop using AI tools. It is to add a review layer between generation and production.

Three weeks before a launch, I ran a review over a product that had been built almost entirely in Cursor across two months. I was not worried. The app worked. Every flow had been clicked through by hand: sign up, connect account, run the core feature. Nothing was broken.

The review returned a critical authentication bypass. Anyone who knew the shape of the request could read any other user's account. The AI had written it cleanly, confidently, and completely wrong, and it had been sitting in the codebase for six weeks without a single test failing.

That gap between *works* and *correct* is the entire subject of this post.

What is vibe coding?

Vibe coding is building software by describing what you want in natural language and letting an AI write the implementation. You hold the product in your head; the model holds the syntax. Tools like Cursor, GitHub Copilot, Claude Code, Bolt, and Lovable have made this workable for millions of people who would never have shipped software otherwise.

The term was popularised by Andrej Karpathy in early 2025 to describe a mode of working where you stop reading every diff and start trusting the model's output the way you'd trust a compiler. The productivity gain is real and it is very large. A non-technical founder can now put a working SaaS product in front of users in a weekend.

The part that gets discussed less: you have also accepted every assumption the model made on your behalf, and you have no record of what those assumptions were.

Why does AI-generated code break in production?

The model is not making mistakes the way a tired engineer makes mistakes. It is producing code that matches the *pattern* of correct code without necessarily having the *properties* of correct code. Those are different things, and the difference is invisible on a screen.

Consider what these models learned from. The training distribution skews heavily toward tutorial code written to demonstrate one concept, open-source examples optimised for readability, and Stack Overflow answers optimised for brevity. In all three, error handling is trimmed for clarity, authorisation is assumed to be handled elsewhere, and the adversarial case is out of scope. Security hardening is systematically underrepresented in exactly the corpus the model is imitating.

The AI had written it cleanly, confidently, and completely wrong. Nothing in the file looked out of place, which is precisely why nobody caught it.

So you get output that implements the happy path correctly and handles the adversarial path incorrectly. Reliably. Every time. That reliability is actually good news: predictable failures are findable failures.

The four failure classes that account for most incidents

1. Silent failures

Your app calls an external API. At 02:00 the API returns a 500. The generated code continues as though the call succeeded. No throw, no log, no alert. Users see empty or wrong data and you find out from a support ticket four days later.

The pattern that causes it
// Generated: happy path only
const res = await fetch(url)
const data = await res.json()   // res.ok is never checked
return data.items                // undefined on a 500 → silent empty state

// What it needs
const res = await fetch(url, { signal: AbortSignal.timeout(5000) })
if (!res.ok) throw new UpstreamError(res.status)
const data = await res.json()
return data.items ?? []

2. Authentication that authenticates but does not authorise

This is the single most common critical finding in AI-generated backends. The endpoint correctly verifies *that you are logged in* and then never verifies *that the thing you asked for belongs to you*. Change an ID in the URL and you read someone else's record. It is catalogued as IDOR, and it accounts for a large share of real-world data exposure.

Authenticated, not authorised
// Generated: any logged-in user can read any document
router.get('/api/documents/:id', authenticate, async (req, res) => {
  const doc = await Document.findById(req.params.id)
  return res.json(doc)
})

// Ownership enforced in the query itself
router.get('/api/documents/:id', authenticate, async (req, res) => {
  const doc = await Document.findOne({
    _id: req.params.id,
    userId: req.user.id,        // never from the request body or params
  })
  if (!doc) return res.status(404).json({ error: 'Not found' })
  return res.json(doc)
})

3. Business-logic drift

You described your pricing in a sentence. The model implemented the average of every pricing system in its training data. Those are close, and close is worse than wrong. A wrong implementation fails loudly in testing, a nearly-right one under-charges every customer by a small amount that compounds silently for months.

This is the failure class that static analysers structurally cannot catch, because there is no bug in the code. The syntax is valid, the types check, the tests pass. It computes the wrong number correctly. The only way to catch it is to give the reviewer your actual business rules and have it check the implementation against them.

4. N+1 database queries

The model writes a loop and queries inside the loop. With the ten rows in your seed data it is instant. With ten thousand rows in production it opens ten thousand connections and the database stops answering. This is the most common cause of an app that was fine in staging and fell over on launch day.

Why does normal testing miss all four?

Because testing checks whether the thing you built does what you intended. All four failures above occur when something happens that you did not intend and therefore did not write a test for: an upstream service failing, a user modifying a request, a rule being subtly misread, a table getting large.

FailurePasses tests?Visible in demo?Cost when found in production
Silent API failureYesNoCorrupted data, discovered late
Missing authorisationYesNoData breach, disclosure obligations
Business-logic driftYesNoRevenue leakage, refunds, trust
N+1 queriesYesNoOutage under first real load

Every row is the same shape: passes, invisible, expensive. That is the signature of a problem that needs a different detection method rather than more of the same testing.

So should you stop vibe coding?

No. The velocity is real and giving it up is a bad trade. Going back to hand-writing every line to avoid four known failure classes is like refusing to drive because seatbelts exist.

What is missing is the step between generation and production. You already have generation covered by tools that are extremely good at it. What you need is something that reads the output with the assumption that it is wrong, checks the specific things models reliably get wrong, and tells you in plain language what it found. That is a thirty-second step, and it is the difference between finding the authorisation bug yourself and having a stranger find it for you.

If you want the concrete version of that step, the five-point pre-deployment checklist covers exactly what to check and in what order. If your product handles payments or user records and you do not have an engineering background, start with code review for non-technical founders instead.

Frequently asked questions

What does vibe coding mean?

Vibe coding is building software by describing what you want to an AI in natural language and shipping the code it produces, rather than writing and reviewing each line yourself. The term was popularised by Andrej Karpathy in 2025.

Is vibe coding safe for production applications?

It is safe when a review step sits between generation and deployment. On its own it is not, because language models reliably produce four classes of defect (silent error handling, missing authorisation checks, business-logic drift, and N+1 queries) that pass tests and stay invisible in demos.

Why does AI-generated code pass tests but still fail?

Tests verify that the code does what you intended. AI-generated defects occur in scenarios you did not intend and therefore did not test: an upstream API failing, a user modifying a request parameter, a table growing past seed-data size.

Can linters or static analysis catch AI-generated bugs?

They catch some. Linters find syntax and style problems and some injection patterns, but they cannot detect business-logic drift, because there is no defect in the code itself. It correctly computes the wrong answer. That requires a reviewer that knows your business rules.

How long does it take to review AI-generated code?

A specialist review of a typical file completes in about thirty seconds when it runs checks in parallel. Manually applying the same checks takes an experienced engineer roughly fifteen to forty minutes per file.

Sources

  1. Vibe codingOrigin of the term, coined by Andrej Karpathy in February 2025.
  2. Do Users Write More Insecure Code with AI Assistants? (Stanford, 2022)Controlled study finding participants with an AI assistant wrote less secure code while believing it was more secure.
  3. OWASP Top 10The consensus list of the ten most critical web application security risks.

Run a free review on the code you are about to ship. Three credits, no card.

Start free