How to fix a Cursor app
that keeps crashing.
Your Cursor-built app worked yesterday. It crashes today. You've asked Cursor to fix it five times and now more things are broken. Here's the 60-minute diagnostic flow we use on every cleanup project, in order — so you can find the actual cause instead of letting the AI play whack-a-mole.
Stop letting Cursor "fix" it
The first rule when a Cursor app is crashing: stop prompting Cursor to fix it. Every re-prompt rewrites code you haven't read, and a model that doesn't know the real cause will confidently break three more things trying to fix the one. Take your hands off the chat panel and run the diagnostic below before you touch the code.
Step 1 — Find the actual error (5 min)
The crash you're seeing in the UI is usually two errors deep from the real one. Look in three places, in this order:
- Production logs. Vercel → Logs tab. Railway → Deployment → Logs. Look for the first error after a successful deploy. That's almost always the root cause; everything after is downstream.
- Browser console. Open DevTools → Console. Filter by "Error". Read the stack trace — not just the top line.
- Network tab. Filter by "Failed" requests. A 500 from your own API is the most common Cursor-app crash and Cursor rarely catches it in chat.
Write the error down before you do anything else. If you can't summarise the failure in one sentence, you can't fix it.
Step 2 — Check environment variables (5 min)
This is the single most common cause of "it works locally but crashes in production" — and Cursor cannot debug it from the chat because it can't see your hosting dashboard.
- Open Vercel/Railway → Settings → Environment Variables.
- Cross-reference against your
.env.localfile. Every key in.env.localneeds to also exist in production. - Watch for the classic Cursor mistake:
NEXT_PUBLIC_*vs unprefixed. Anything that needs to be available in the browser must start withNEXT_PUBLIC_. - Redeploy after adding any missing vars — Vercel doesn't pick them up until a new build runs.
Step 3 — Audit the database queries (15 min)
If logs aren't conclusive, the next suspect is the database. Cursor writes queries that work — but it doesn't write queries that scale. Look for these patterns:
- N+1 queries — a list page that runs one query per row. Symptom: page loads slowly with many items, fast with few.
- Missing indexes — queries against unindexed columns. Symptom: response time grows linearly with row count.
- Unbounded queries —
SELECT * FROM tablewith noLIMIT. Crashes when the table grows past a few thousand rows. - Race conditions — two concurrent inserts violating a unique constraint. Symptom: random 500s under light load.
In Supabase: Dashboard → Database → Query Performance. Anything over 200ms is a candidate. In Postgres directly: EXPLAIN ANALYZE on the slow query reveals the real cost.
Step 4 — Verify the build output (5 min)
Cursor occasionally updates a file but the changes don't make it into the deployed build because of a TypeScript error that the model "fixed" by silently adding @ts-ignore. Two checks:
- Run
npm run buildlocally. If it fails or warns, your production build is shipping broken code. - Check git:
git log --oneline -10. Are your latest commits actually deployed? Vercel sometimes caches an older build.
Step 5 — Refactor the failing module (30 min, or call us)
If the same module has crashed three times and Cursor keeps re-introducing the bug, the file structure itself is the problem. Symptoms:
- One file is over 500 lines.
- Multiple components share mutable state via props drilling.
- Business logic lives inside React components.
- The same API call appears in three places.
The fix is to split the file into smaller modules, lift state into a single source of truth, and move business logic into pure functions outside of components. Cursor cannot do this well because it operates one file at a time. This is a human-shaped problem.
If you're not sure how to do that, this is exactly what our Weekend Cleanup (₹4,999) handles. Send us the repo, we send back a refactored module within 48 hours.
The fixes that almost always work
If you only do three things this week:
- Add a
try/catchwrapper around every API route handler. Cursor rarely does this and uncaught errors are responsible for ~40% of production 500s we see. - Add
LIMIT 100to everySELECTthat returns a list. Stops table-scan crashes when data grows. - Pin your dependencies. Open
package.jsonand remove the^from versions. A silentnpm installupgrading a dep is the cause of half the "it broke overnight" incidents.
Cursor still looping on the same bug?
When the AI is stuck in a fix-loop, the codebase needs a human to break the cycle. We do that for ₹4,999 in a weekend.
Get my free audit