← Back to blog

The Vibe Coded SaaS Calls I'm Getting Now (And What I Actually Fix)

6 Nov 2026 · 4 min read

A few months back I had three separate enquiries in the same week, all with the same shape. A founder had built something impressive with ChatGPT or Claude or Cursor, got a working demo, started taking real signups, and then hit a wall. Stripe webhooks silently failing. Users seeing each other's data. A migration that half ran and left the database in a state nobody could explain. None of them used the words "vibe coded" but that's exactly what had happened, and I mean that as a description, not an insult.

I want to be clear about something before I go further. AI tools are genuinely good. I use Claude and Copilot every single day inside Laravel Boost and they save me hours on boilerplate, on writing tests, on working through an unfamiliar package's API. The problem was never the AI. The problem is using it as a replacement for understanding rather than an extension of it.

What an AI assistant actually is

Think of it like hiring a very fast, very confident junior developer who has read every Laravel tutorial ever written but has never shipped anything to production and has never had a 3am phone call about a down site. That developer will write code that runs. It will often look clean. It will almost never ask "what happens if two users submit this form at the same time" because that question only comes from having been burned by it before.

That's the gap I keep finding. Not bad code exactly, just code written by something that has never felt the consequences of getting it wrong.

The patterns I see over and over

A few things turn up in nearly every vibe coded project I've been asked to fix:

  • Mass assignment with $fillable set to everything, including is_admin and role, because it made a form work faster during development
  • Eloquent relationships that look right but return the wrong tenant's data because there's no global scope, no policy, nothing stopping a user from changing an ID in the URL
  • Stripe webhook handlers that don't verify the signature, or worse, don't exist at all and the app just trusts whatever the frontend tells it about payment status
  • Queries running inside loops, sometimes four or five hundred queries to render one dashboard, because nobody told the AI that with() exists
  • Migrations edited after they'd already run in production, so the schema in the repo and the schema on the server have quietly diverged
  • Entire features built around a package that doesn't exist, hallucinated from a half-remembered blog post, with a composer require that was just never run

None of this is a moral failing on the founder's part. If you don't know Laravel, you don't know what questions to ask the tool, and the tool will happily answer confidently anyway.

What fixing it actually looks like

I don't usually start by rewriting everything, much as part of me wants to. Most of these apps have real users and real revenue, so the first job is triage. I'll pull up Laravel Telescope or just tail the logs for a day, find what's actually breaking right now, and patch that. Usually it's an N+1 problem crushing a dashboard, or an unguarded route that any logged in user can hit regardless of which account they belong to.

Then it's a slower pass. Adding policies where there were none. Wrapping payment logic in proper webhook verification. Writing a handful of Pest tests not for coverage numbers but so the next change doesn't silently break billing again. Sometimes that means pulling business logic out of a 600 line Livewire component and into something that can actually be tested in isolation.

The twenty five years doesn't make me faster at typing. It makes me faster at knowing which of the forty problems in front of me will actually hurt someone this week, and which can wait until next month.

If this sounds like your project

If you've built something with AI help and it's starting to creak under real users, that's not a failure. It's actually a good sign, it means people want what you built. Get someone to look at it before the creaking turns into a 3am call. I'd rather spend two hours reading your codebase and telling you honestly what state it's in than have you find out the hard way during a traffic spike.