You've spent 48 hours straight coding with an AI assistant. Cursor generated your auth flow, Claude set up your database, and Bolt helped you hook up Stripe. Everything works on localhost. You're feeling like a god. Time to deploy, right?
Hold up.
Here's the thing nobody tells you about AI coding: it gets you about 60% of the way there. The last 40%? That's where every vibe-coded app fails. And AI assistants won't warn you about it because they don't know what production-ready actually means.
Let's talk about the 7 bugs AI won't catch before you ship.
1. Stripe Test Keys in Production
What it is: You forgot to swap pk_test_ and sk_test_ for live keys in production. Those keys end up in your bundle and payment flow.
What happens if you ship it: Customers click pay and nothing happens. No charge. No clear error. Revenue appears to go flat for weeks.
How to fix it: Never hardcode keys in code. Validate env vars at boot and fail fast.
if (process.env.NODE_ENV === 'production' && !process.env.STRIPE_PK?.startsWith('pk_live_')) {
throw new Error('Stripe live key required in production');
}

2. Missing Webhook Signature Verification
What it is: Your /api/webhook/stripe endpoint accepts any POST as a valid event. No signature check, no validation.
What happens if you ship it: Anyone can send fake “subscription activated” events. People get premium access for free until your model is economically broken.
How to fix it: Verify every event with your webhook signing secret.
const signature = request.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(
payload,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
3. Exposed .env File
What it is: Your server doesn't block /.env. If someone guesses that path, your secrets are one curl away.
What happens if you ship it: Attackers pull API keys, database passwords, JWT secrets, and begin exploitation immediately.
How to fix it: Block secret file paths at app and edge/server levels.
app.use((req, res, next) => {
if (req.path === '/.env' && process.env.NODE_ENV === 'production') {
return res.status(404).end();
}
next();
});

4. No Rate Limiting on Login
What it is: Your auth endpoint accepts unlimited password attempts and does not rate limit or throttle.
What happens if you ship it: Botnets lock out your users, or brute force attacks slowly break credentials.
How to fix it: Add rate limiting middleware and enforce strict attempt budgets.
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5,
});
app.post('/api/login', limiter, loginHandler);
5. Default Error Pages Leaking Stack Traces
What it is: You rely on default framework error pages in production.
What happens if you ship it: Stack traces and internal paths leak into the UI, giving attackers a roadmap of your infrastructure.
How to fix it: Use generic production error responses and structured logging on server side.
app.use((err, req, res) => {
if (process.env.NODE_ENV === 'production') {
res.status(500).send('Something went wrong.');
} else {
console.error(err);
res.status(500).send(err.stack);
}
});
6. Missing Security Headers
What it is: Your app has no CSP, no HSTS, no clickjacking protections, and weak browser defenses.
What happens if you ship it: XSS, clickjacking, and downgrade attacks become easier.
How to fix it: Enable a security middleware like Helmet with strict defaults.
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: true,
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
}));

7. No Health Endpoint
What it is: Your app has no /healthz or /status endpoint for monitoring.
What happens if you ship it: You discover outages when customers do, not when your systems can.
How to fix it: Expose a simple DB + dependency check endpoint for uptime monitors.
app.get('/healthz', async (req, res) => {
try {
await db.query('SELECT 1');
res.status(200).json({ status: 'healthy' });
} catch {
res.status(503).json({ status: 'unhealthy' });
}
});
The Bigger Problem
These aren't edge cases. These are the common production failures we see in AI-built apps every week.
AI can draft clean features fast. What it can't do is replace your judgment on production readiness.

Want to check all 7 automatically?
ShipCheck scans your live app and gives you direct fixes, severity, and where to patch first.
Scan Your App Now