---
title: "How to add error monitoring to an AI-built app"
description: "Four layers, from the logs you already have to a dedicated tracker. How to stop finding out your app is broken from an annoyed colleague."
source: "https://www.netlify.com/knowledge-base/add-error-monitoring-to-an-ai-built-app/"
last_updated: "2026-10-21T14:58:51.000Z"
---
## Key takeaways

-   The default state is finding out from an annoyed colleague. That is a monitoring problem, not a quality problem, and the fix is mostly configuration rather than code.
-   Layer one costs nothing: deploy logs, function logs, and observability tied to the deploy that caused a change already exist. Most people have never opened them.
-   Layer two is the one AI-built apps most need, because generated code handles the happy path well and treats failure as unlikely, so errors often surface as something unhelpful rather than as a clear error.
-   Layer three is where it stops being work: notifications, so discovery is pushed to you rather than pulled by you.
-   Most internal tools should stop at layer three. A dedicated error tracker is genuinely better once volume rises, and it is overkill for twelve people and a form.

Your app is live and people use it. Somebody mentions in passing that the export has been failing since Tuesday, and you realize that you had no way of knowing, and that this is probably not the first time.

That is the normal state for tools built this way and it is entirely fixable. Most of the fix is not building anything, it is knowing what already exists and switching on the part that tells you. Four layers, in the order worth doing them.

## Layer one: read what you already have

Before adding anything, learn the three surfaces that are already recording.

Deploy logs tell you whether a change built and shipped, and when a build fails, why. This is the first place to look when something stopped working right after you changed it, which is the most common case by a wide margin.

Function logs show what your server-side code actually did: what was called, what it returned, what threw. If your app has any logic beyond displaying pages, this is where its behaviour is visible. On Netlify these sit with [Netlify Functions](https://www.netlify.com/platform/functions/) and are per-invocation.

Then there is [observability tied to each deploy](https://www.netlify.com/platform/observability/), which is the one that answers the question you actually have. Traffic, performance, and function health attach to the specific deploy that moved them, so “what changed on Tuesday” has an answer rather than requiring you to correlate two timelines by eye.

Spend twenty minutes finding these before you build anything. A surprising share of monitoring problems are really navigation problems.

## Layer two: make your app produce useful errors

Here is where AI-built apps need the most help, and the reason is specific to how they are written.

Generated code handles the happy path beautifully and treats failure as unlikely. When something unexpected arrives, the typical result is not a clear error. It is a blank screen, a silent no-op, or a success message for something that did not happen. The failure is real and nothing anywhere records it as a failure.

The fix is to ask for it explicitly, and this is a reasonable thing to delegate. A prompt along the lines of: “wrap the operations that can fail in error handling, log the failure with enough context to identify which record and which user it happened to, and return a message that tells the person what went wrong rather than failing silently.”

Three things make a logged error useful. What happened, in words rather than a code. Which case it happened to, so you can reproduce it. And when, which you get for free.

The thing to avoid is logging everything. A log that records every successful operation buries the twelve lines you needed. Log failures and decisions, not activity.

## Layer three: get told rather than going to look

Layers one and two are passive. They record, and you have to go and look, which means you find out when you happen to check.

Notifications close that gap, and this is the highest value-per-minute step on the page.

Start with deploy failures, which is the simplest useful alert and catches the case where you pushed a change and it never went live. Then function error rates, so a spike gets pushed to you rather than waiting to be discovered. Route both somewhere you actually read, which for most teams is a chat channel rather than email.

The discipline that makes this work is restraint. An alert that fires constantly gets muted within a week, and a muted alert is worse than no alert because it creates the impression of coverage. Alert on things that are both unexpected and actionable. If you cannot describe what you would do when it fires, it should not fire.

For a small internal tool, two alerts is a reasonable permanent configuration.

## Layer four: a dedicated error tracker, when you outgrow logs

At some point logs stop being enough, and there is a clear signal for when.

You have outgrown them when you are doing any of these: trying to work out how many distinct users hit a problem, trying to tell whether an error is new or has been happening for months, or scrolling to find the error you know is in there somewhere. Logs are a stream. Once you need aggregation, grouping, and history, you want a tool built for that.

A dedicated error tracker groups identical errors, counts occurrences and affected users, tells you when something first appeared, and captures the state at the moment of failure. Connecting one is usually a small amount of setup, and asking an agent to add it is a reasonable task.

The honest guidance: most internal tools never need this, and adding it early is a way of feeling thorough rather than being it. Volume is the trigger. Twelve people and a form will not generate enough errors for aggregation to beat reading the logs.

## What counts as an error worth your attention

Worth separating three things that all look like errors and warrant different responses.

Expected failures are not errors. A user submitted an invalid form and got told so: the system worked. These should be visible if you go looking and should never alert.

Handled problems are worth logging, not waking up for. An external service was briefly unavailable, the retry succeeded. You want this recorded because a pattern of it matters even though no single instance does.

Unhandled failures are the real thing. Something threw that nobody anticipated, and a person got a broken experience. These are what layer three should notify on, and in a well-behaved app they should be rare enough that each one is worth looking at.

The reason to draw these lines deliberately is that generated code tends not to distinguish them, so everything looks equally urgent until you decide otherwise.

## A starting configuration

For a typical internal tool with real users and modest traffic, this is a sensible place to stop.

Know where the deploy logs, function logs, and per-deploy observability live, and check them when something is reported.

Have your app log failures with enough context to identify the case, and return messages that say what went wrong.

Have two notifications: failed deploys and a function error-rate spike, routed to a channel you read.

Skip layer four until you catch yourself scrolling logs to count things.

That configuration takes under an hour, most of it in layer two, and it moves you from finding out by complaint to finding out by notification. Which is the entire point.

## Testing that it works

One step people skip: verify the monitoring before you need it.

Deliberately cause a failure in a [Deploy Preview](https://www.netlify.com/platform/core/deploy-previews/), which gives you a complete running copy at its own URL with its own database branch, so you can break things properly without touching real records. Then check that the error appears where you expect and that the notification fires.

Monitoring that has never been tested is a guess. The failure mode is discovering during a real incident that the alert was misconfigured, which is the worst possible moment to learn it.

## FAQs

**How do I add error monitoring to an AI-built app?** Four layers. Learn the deploy logs, function logs, and per-deploy observability you already have. Ask your agent to add error handling that logs failures with context rather than failing silently. Set up notifications for failed deploys and function error-rate spikes. Add a dedicated error tracker only once log volume makes aggregation necessary.

**Why doesn’t my app show errors?** Because generated code tends to handle the happy path thoroughly and treat failure as unlikely. The common result is a blank screen, a silent no-op, or a success message for something that did not happen. The failure is real, nothing records it as a failure, and the fix is explicitly asking for error handling and logging.

**What should I actually alert on?** Failed deploys and a spike in function errors is a reasonable permanent set for a small tool. Resist alerting on expected failures such as invalid form submissions, and on handled problems such as a retry that succeeded. If you cannot say what you would do when an alert fires, it should not fire.

**Do I need a dedicated error tracking tool?** Most internal tools do not. The signal that you have outgrown logs is wanting to count how many users hit something, tell whether an error is new, or scroll to find a known error. Those are aggregation problems, which is what a tracker provides and a log stream does not.

**How do I test that monitoring works?** Break something on purpose in a deploy preview, which has its own database branch so real records are untouched, then confirm the error shows up where you expect and the notification fires. Monitoring that has never been exercised is an assumption, and incidents are a bad time to discover a misconfiguration.

**Where do I find logs on Netlify?** Three places, for three questions. Deploy logs for whether a change shipped and why a build failed. Function logs for what server-side code did on a given invocation. Per-deploy observability for traffic, performance, and function health attached to the change that caused them.

## Related

-   [How to deploy an AI-generated app without losing control of it](https://www.netlify.com/knowledge-base/deploy-an-ai-generated-app-without-losing-control/)
-   [From prompt to production: what “production-ready” actually means for an AI-generated app](https://www.netlify.com/knowledge-base/what-production-ready-means-for-ai-generated-apps/)
-   [What does “production-ready” actually mean for workers who don’t code?](https://www.netlify.com/knowledge-base/production-ready-for-workers-who-dont-code/)
-   [How to add a backend API endpoint with Netlify Functions](https://www.netlify.com/knowledge-base/how-to-add-a-backend-api-endpoint-with-netlify-functions/)
-   [Why your deploy preview can delete Netlify Blobs data](https://www.netlify.com/knowledge-base/why-your-deploy-preview-can-delete-netlify-blobs-data/)

* * *

Spend twenty minutes finding the logs you already have, then an hour on layers two and three. If you want somewhere that ships all three surfaces by default, start at [netlify.new](https://netlify.new).