Error tracking for AI-generated code and vibe apps

Shipped an app from Cursor, Lovable, or Bolt? One script tag captures production errors — stack trace, browser, frequency — ready to paste into your agent.

Catch Team··8 min read

If you shipped an app built with Cursor, Lovable, Bolt, or Claude Code, add error tracking before you touch anything else. It's one script tag and about five minutes, and it matters more for you than for a traditional team: you didn't write — and probably haven't read — every line of that codebase, so when it breaks for a real user you have no mental model to debug from. What you need is the actual error: stack trace, browser, URL, how many users hit it. An error tracker captures all of that, groups repeats into issues, and hands you something to paste straight back into the agent that wrote the code.

Why do AI-generated apps break in production?

Because production is where the inputs you never tested live. AI-generated apps work in the demo — you built the happy path, prompted until it passed, and clicked through it yourself in one browser with your own data. Real users bring everything else: a date field that arrives as null, a 40,000-character paste into a textarea, Safari parsing a date string differently than Chrome, two requests resolving in the order you didn't expect.

To be clear, vibe coding's production errors are the same errors every app has. What's different — now that the practice is mainstream enough that Collins named "vibe coding" its Word of the Year 2025 — is what's missing around the code. A traditional team has a reviewer who flagged the unguarded null, a test that exercised the weird input, and someone who remembers why the module exists. A solo builder shipping a Lovable app has none of that. The first error report is a DM that says "hey, I think checkout is broken?" — and that's the lucky case. Mostly it's silence: users don't report bugs, they leave.

And when the DM does arrive, it contains nothing you can act on. "It's broken on my phone" has no stack trace, no URL, no browser version. You can't debug an AI-generated app from that — and neither can the AI that generated it.

The debugging loop: paste the error into your agent

A structured error report is exactly the context a coding agent needs — which makes "paste the error into the agent" the tightest debugging loop available to you. Agents flail when they have to guess what went wrong; they're effective when handed the precise failure: the exception message, the stack frame in your code, the browser, the route, how often it fires.

Compare what you get from a user with what you get from an error tracker:

QuestionA user DMYour error tracker
What broke"checkout doesn't work"TypeError: Cannot read properties of null (reading 'total')
WhereunknownapplyPromo in cart.ts:42, symbolicated via source maps
Browser / device"my phone"Safari 26 on iOS
How many usersone, maybe14 events, 9 users, first seen 2 hours ago
Which pageunknown/checkout?promo=SPRING

The loop, end to end:

  1. The error lands in your dashboard, which dedupes it and groups its repeats into one issue.
  2. Copy the full context — message, stack trace, browser, URL, event count.
  3. Paste it into Cursor or Claude Code: "Users are hitting this in production. Find the cause and fix it."
  4. Ship the fix.
  5. Watch the issue. If events stop, it worked. If they keep coming, the agent fixed the wrong thing — go around again.

A practical note on step 3: paste everything, not just the first line. The frames below the top of the stack tell the agent which call path triggered the failure, and the browser and URL stop it from "fixing" code that never ran on that page. Agents are good at ignoring irrelevant context and terrible at inventing missing context.

Step 5 is the part you cannot get any other way. Without tracking, "fixed" means "nobody has complained since lunch," and we've already covered how reliable that signal is. With tracking, the issue's event count goes quiet and you know.

(Agent tooling is drifting toward wiring this context in directly — that's what the Model Context Protocol is for — but copy-pasting a good stack trace already gets you most of the value.)

How do you add error tracking to an AI-generated app?

One script tag, no build step. To monitor an app built with Cursor — or anything that ends up as HTML in a browser — paste this into your <head> before other scripts. It loads Catch's browser SDK from a CDN and immediately starts capturing uncaught errors and unhandled promise rejections:

<script
  src="https://unpkg.com/@catch.dev/browser-script/dist/browser-script.js"
  data-key="ck_live_your_key"
  data-environment="production"
  data-version="1.0.0"
></script>

data-key is your app's access token (in the dashboard: your App → API Keys). data-environment keeps local-dev noise out of your production view. data-version is worth the extra line — bump it on each deploy (a commit SHA works) so every error report tells you which version of the app threw it. And yes, telling your agent "add this script tag to the app shell" is a perfectly legitimate install method.

Under the hood this rides the browser's global error hooks. If you're curious what those actually catch — and the gaps between them — we wrote up window.onerror vs addEventListener('error'). The point of an SDK is that you don't have to care.

With a build step

If your tool produced a real repo — a Cursor or Claude Code project, or an app builder's GitHub export — install the package that matches the stack instead:

npm install @catch.dev/react   # or @catch.dev/next, @catch.dev/express, @catch.dev/nest

The getting-started guide covers the wiring for each framework; the promise on that page is your first captured error in under five minutes. One honest scope note: our error SDKs are JavaScript/TypeScript only — which, conveniently, is what every one of these tools generates. There's a free tier with no credit card required, which fits most vibe-coded projects on day one.

Make the stack traces readable

Production bundles are minified, and at t (index-3f9c1b.js:1:48211) is as useless to your agent as it is to you. Upload source maps — via the CLI or a build plugin — and Catch symbolicates stack traces server-side back to real files and line numbers. If you do one configuration step beyond the script tag, do this one. It's what makes the paste-into-agent loop work on production errors.

What should you fix first in week one?

Fix the issue affecting the most users, and expect some noise — there will be noise. The first week of error monitoring on any app, a Lovable export or hand-written, surfaces a layer of browser weirdness that was always there. Don't let it spook you. The dashboard groups errors into issues and shows how many users each one affects; sort by that, not by raw event volume.

The usual first-week suspects:

First-week errorWhat it usually isWhat to do
Script error. with no stackA cross-origin third-party script — browsers deliberately limit the detailsIgnore, unless a feature broke at the same time
ResizeObserver loop completed with undelivered notificationsA benign browser quirkIgnore
Failed to fetch / Load failed, scattered thinlyFlaky networks, ad blockersIgnore unless it spikes on one endpoint
Stack frames from chrome-extension://A user's browser extension, not your codeIgnore
A TypeError in your own code, hitting several usersA real bugThe loop above

Work one issue at a time: one error, one paste, one fix, one deploy. Resist bulk-forwarding the whole first week to your agent in a single prompt — you lose the per-issue signal that tells you whether each fix actually landed.

Then set up exactly one alert: new issue → Slack (or email). Not an alert per event — per new issue. You want to hear about each new way the app breaks once, not four hundred times.

What error tracking won't fix

It won't make the code good. Error tracking doesn't replace tests, review, or actually reading what the agent wrote — it's the net under the tightrope you were going to walk anyway. A few more things it won't do:

  • Logic bugs that don't throw. If the promo code happily applies a 100% discount, no exception fires and nothing gets reported. Only a human — or a pointed test — notices.
  • Tell you the site is down. If the page never loads, no SDK runs to report anything. That's uptime monitoring, a different tool.
  • Read the errors for you. Triage is still a habit. A small one — five minutes with coffee — but yours.

And sometimes the right amount of tooling is less than this. If you're weighing options, we compared lightweight Sentry alternatives for small teams — including the cases where a plain global handler and a log file are genuinely enough.

But if real people are using an app whose every line you can't personally vouch for, the calculus is short. You shipped code you didn't fully read. The least you can do is read its errors.

Catch Team

Building catch.dev — the tiny SDK for in-app feedback and crash reports.

// More from the blog