← Back to blog

The 12 Things That Kill Vibe-Coded App Launches

AI code assistants are fast but they cut corners. Here are the 12 most common ways vibe-coded apps fail in production.

Asenvra

You built your app with Cursor. Or Lovable. Or Bolt. It works on your machine. The demo looks great. You're ready to ship.

But here's what nobody tells you: AI code assistants are optimization engines. They optimize for it works right now, not for it works in production with real users and real data.

After scanning thousands of vibe-coded projects, here are the 12 issues we see over and over again — the ones that turn a "ready to ship" app into a "how did this break?" nightmare.

1. Hardcoded API Keys in Source Code

This is the #1 issue. AI assistants love to put your sk-live-... keys directly in your source files. It "works" because the code can find the key. But anyone who sees your code — a public repo, a leaked ZIP, a collaborator — now has your keys.

What happens: Attackers scan GitHub constantly. A stolen Stripe key means surprise bills. A stolen OpenAI key means someone else running GPT-4 on your dollar.

Fix: Move every secret to .env files. Never commit .env to Git. If a key was ever in a public repo, rotate it immediately.

2. Mock Data in Production

test@example.com. John Doe. const mockUsers = [...]. Your AI assistant needed data to make the UI work, so it made some up. And then it never removed it.

What happens: Real users see fake names, fake emails, and fake data. They assume the app is broken, untrustworthy, or a scam. First impression destroyed.

Fix: Replace every hardcoded test value with real data from your database or API. If there's no data yet, show an empty state message like "No items yet" instead of fake entries.

3. Missing Environment Variables

Your app references process.env.STRIPE_KEY but you never set it in production. Everything works locally because your .env.local has the values. But Vercel, Railway, and Render don't have your local env file.

What happens: Instant crash on deploy. The app throws "undefined is not a string" errors that are confusing and hard to debug remotely.

Fix: Create a .env.example file listing every variable your app needs. Before deploying, go through each one and make sure it's set in your hosting platform's dashboard.

4. Wide-Open CORS Configuration

origin: "*" in your CORS config. AI assistants set this because it "fixes" the CORS error during development. But it means any website on the internet can make requests to your API.

What happens: An attacker builds a malicious site that makes requests to your API using a logged-in user's credentials — stealing their data or performing actions on their behalf.

Fix: Replace the wildcard with your specific domain. Only allow https://yourapp.com. You can set multiple allowed origins in your CORS config.

5. No Rate Limiting

Your API endpoints have no rate limiting. AI assistants don't add rate limiting because it's not needed for the demo. But in production, anyone can call your endpoints millions of times.

What happens: A single user (or bot) can overwhelm your server, run up your API bills, or scrape all your data. One abusive script can take down your entire app.

Fix: Add rate limiting middleware. Most frameworks have plugins: express-rate-limit, Django REST Framework throttling, Next.js middleware with a token bucket. Start with 100 requests per minute per IP.

6. Supabase RLS Disabled

Row Level Security is disabled on your Supabase tables. Your AI assistant created the tables but didn't set up RLS policies because the app "works" without them.

What happens: Anyone with your anon key (which is public) can read, modify, or delete every row in every table. All user data is exposed.

Fix: Enable RLS on every table. Create policies that restrict access: users can only see their own data, public data is read-only, and writes require authentication.

7. Placeholder Copy in Live UI

"Coming soon." "Lorem ipsum dolor sit amet." "Your text here." Your AI assistant filled in content with placeholder text, and you never replaced it.

What happens: Users see "Lorem ipsum" and think the app is half-built. Even if the rest works perfectly, placeholder text screams "I was built by AI and never checked."

Fix: Replace every piece of placeholder text with real, meaningful content. If a section isn't ready, remove it entirely rather than showing filler.

8. Debug Flags Left On

console.log everywhere. debug: true in production config. Verbose error messages that reveal your code structure. All the things you meant to turn off before shipping.

What happens: Performance drops. Sensitive data leaks to the browser console. Error pages reveal your code structure, database queries, and environment variables to anyone who triggers an error.

Fix: Set NODE_ENV=production. Remove console.log statements or replace with a proper logging library. Disable debug mode in all frameworks.

9. No Error Boundaries

Your app has no error handling. When something goes wrong — a failed API call, a missing database record, a network timeout — the app shows a blank screen or crashes entirely.

What happens: One broken feature takes down the entire page. Users see a white screen with no explanation. They think the app is broken and leave.

Fix: Add error boundaries in React. Wrap fetch calls in try/catch. Show user-friendly error messages. At minimum, show "Something went wrong. Please try again." instead of a blank screen.

10. Missing Auth Middleware

Your protected routes only check auth on the frontend. The backend API routes have no authentication — they trust that the frontend wouldn't show the UI to unauthenticated users.

What happens: Anyone can call your API endpoints directly, bypassing the UI entirely. They can create accounts, delete data, or access other users' information.

Fix: Every protected API route must verify the session server-side. Check the session at the top of your route handler. If there's no valid session, return 401 Unauthorized.

11. No .env.example File

Your project has no .env.example file. New developers (or you on a new machine) have to guess what environment variables to set. This causes hours of debugging "undefined is not a string" errors.

What happens: Onboarding is painful. Deployments fail silently. Everyone wastes time figuring out what variables the app needs.

Fix: Create .env.example with every variable your app needs, placeholder values, and comments explaining what each one does.

12. No Deploy Configuration

No Dockerfile. No CI/CD pipeline. No platform-specific config. Your app runs locally and nowhere else. AI assistants build apps that work in development — they don't set up production infrastructure.

What happens: You can't deploy. You spend days figuring out how to get your app from your laptop to the internet. Or you deploy with wrong settings and it crashes.

Fix: At minimum, create a vercel.json or railway.toml. Set NODE_ENV=production. Add a Dockerfile for containerized deploys. Use Asenvra's VibeOps tool to auto-generate deployment configs.


The Bottom Line

Vibe-coded apps work. The code runs. The features are there. But "works on my machine" is not the same as "works in production with real users."

The good news: Every one of these issues is fixable. Most take minutes to fix once you know they're there.

The better news: Asenvra scans for all 12 of these — and 7 more. Upload your project or paste a GitHub URL and get a plain-English report of exactly what to fix before you ship.

Scan your own code free — no credit card needed

Scan your own code free

Upload your project or paste a GitHub URL. Get a plain-English report of exactly what to fix before you ship.

Run Your First Scan Free →

No credit card needed · 3 free scans/month

Check your app's VibeScore →