Engineering · · 11 min read · Lukas Ceponis
Why AI automations die in production, and the six usual causes
The demo was great. The first two weeks were great. Then an API changed, a model updated, a webhook started sending a slightly different payload, or someone renamed a CRM field, and the workflow started failing quietly, and nobody noticed for a month because nothing was watching it. That is why AI automations die in production in almost every case we have opened up: the model was fine and the engineering around it was missing.
We run six systems in production, our own voice receptionist among them, and we get called into other people's broken ones often enough that the causes have stopped surprising us. What follows is the taxonomy we work from. Each failure has a mechanism, a signature you can spot in an execution list without opening anything, and a page where we take it apart properly.
Why a forum thread is the wrong artifact for this
Search any of these symptoms and the results are mostly community threads. We spent a while trying to prove those threads go unanswered, published a statistic saying so, and then could not reproduce our own number. Here is what we actually found when we measured it properly on 26 August 2026, sampling 600 topics from each forum's Questions category in creation order.
| Forum, Questions category | Topics sampled | With an accepted answer | With no reply at all |
|---|---|---|---|
| n8n community | 600 | 37.0% | 0.0% |
| Make community | 600 | 26.5% | 7.8% |
So people do answer. Our earlier claim that the n8n forum resolves these questions worse than Make's was backwards, and we have removed it. The artefact that produced it is worth knowing if you ever measure a Discourse forum yourself: n8n's Help me Build my Workflow category, 1,549 topics, has solution marking switched off entirely, so any sample touching it returns zeros by configuration rather than by neglect.
What survives is smaller and duller. Around 63% of n8n Questions threads carry no marked solution, and the forum takes roughly 722 new topics a month with about 1,235 people posting. The reason to write a triage guide rather than point at a thread has nothing to do with the forum failing. A thread is one stranger's specific case, answered for their credentials, their payload and their node versions. It ranks for your search and then describes somebody else's morning.
The mechanism is dull. "How do I split an array in a Code node" has one answer that works for everyone who reads the thread. "My workflow runs and nothing happens" has forty candidate causes, and narrowing them takes the execution history, the credential list, the input payload and the last successful run date in front of you. Nobody on a forum has any of that, so the thread fills with guesses, the original poster goes quiet once they solve it or give up, and the topic sits unresolved for two years while ranking on the exact search a panicking owner types at nine in the morning.
Our numbers are a snapshot from one afternoon, one endpoint, and a cap that hides whatever sits on page two.
Working automations die in six ways
Credentials expire or get revoked
This is the most common single cause we find, and it almost never announces itself. A Google OAuth app left in Testing publishing status issues refresh tokens that expire after seven days, which is long enough for a build to pass its acceptance week and die the following Monday. Refresh tokens also die when the account owner changes their password, and when anyone withdraws consent in their Google security settings. On the Microsoft side, an Entra conditional access policy can revoke a session in the middle of a run for reasons that have nothing to do with your workflow.
Slack deserves its own warning. When a token has been revoked, the API answers with HTTP 200 and a body containing ok:false, so a check written against the status code alone records a success and moves on. From the business side this looks like messages that stop arriving, with a green execution list and no error to show anyone. The credential expiry page has the per-provider lifetimes and the health check we run against them.
Silent runs that do no work
A filter matches nothing. A database query returns an empty set. A webhook delivers a body in a shape the first node does not recognise. Every node downstream of the empty point is skipped, and n8n records the execution as a success, because from the engine's point of view nothing went wrong. The dashboard stays green all week while no work is done, and the first person to notice is usually a customer who never got a reply.
The signature is duration. A run that normally takes twelve seconds finishing in 400 milliseconds is a run that did nothing, and it is visible in the execution list at a glance once you know to look. The full diagnosis for a workflow that runs but does nothing walks the places items go missing.
Schema drift on the other side of an API
Vendors add fields, rename fields, nest fields inside new objects, and occasionally change a type, usually with a changelog entry nobody on your side subscribes to. Code that read data.customer.email starts throwing "Cannot read properties of undefined" the morning the payload changes shape. The loud version at least shows up as a red run somebody can point at. The expensive version is quiet: an expression resolves to an empty string, blanks go into the CRM for three weeks, and the repair job turns into a data cleanup with a spreadsheet and an intern.
Rate limits and quota exhaustion
Demos are built on ten test records. Production arrives with 200 runs a day, a Monday morning burst, and a bulk import somebody kicks off without telling anyone. Then the 429s start, or the token-per-minute ceiling on the model account is reached, or the prepaid balance runs out on a Saturday because auto-reload was never switched on. None of this appears during a two-week pilot, which is why the pilot is a poor guide to what the system needs. Platforms differ in how gracefully they behave here, and the difference is part of the tradeoff between Zapier, Make and n8n.
Continue On Fail used as error handling
Somebody hits an error they cannot reproduce, switches on Continue On Fail (Continue Using Error Output in newer builds), the red run turns green, and the ticket closes. The node now passes an error object downstream as if it were data. Every node after it processes a payload carrying a message and a stack trace where the customer record should be. We have opened workflows where this had been on for months, quietly writing junk into a CRM, and the owner's honest belief was that the system had been stable since spring.
No named owner, and no monitoring
Three of the six rescues we have scoped started the same way: the original builder was gone and every account was in his name. No documentation, no admin access, and nobody whose job it is to look. Monitoring is the same problem wearing a different hat. In a lead-routing rescue, an n8n flow handling about 200 runs a day was failing roughly once a day, and its only alert went to a Slack channel that had been archived months earlier, so nobody had seen a single failure. Everything was technically alerting. The order for taking a system back, once a freelancer has disappeared, is accounts first and fixes last, and the handover checklist is the version you run before it happens.
One more belongs to this decade rather than the last: an AI agent that stops calling its tools. The workflow runs, the model answers in fluent prose, and the booking is never made, because a tool description drifted or the system prompt grew until the instructions competed with each other. It presents like a silent zero-item run and it is diagnosed differently, which is why it has a page of its own. Chatbots have a matching failure where the model invents an answer instead of looking one up.
Your evidence has a fourteen day shelf life
n8n prunes execution data on a schedule, and the default EXECUTIONS_DATA_MAX_AGE is 336 hours, which is fourteen days. For a slow-burning failure that means the first bad run has often already been deleted by the time anyone asks when it started. We have sat down to diagnose a system with a month of complaints behind it and found two weeks of history, all of it recorded after the cause.
Two things follow. Raise the retention setting on any self-hosted instance where a run touches money or customers, since disk is cheaper than guesswork. And stop treating a dashboard as monitoring, because a dashboard reports only what somebody looks at, while an alert arrives whether or not anyone is looking. The stopped-working triage page has an error workflow you can import that sends the failure, the node and the payload somewhere a person reads.
The list we ship against
Every build leaves with six things: retries and dead-letter handling on every external call, alerting to a channel a named person reads (and we now check that the channel is not archived), an eval set for every prompt that matters, configuration pulled out of the logic, documentation a stranger could operate from, and accounts in the client's name. Each item maps to one of the failures above. None of it is glamorous, which is the point, because production is boring and boring is what you are paying for. The longer version, with the checks we run before a launch date is agreed, is the production-ready checklist.
An opinion that will annoy some builders: a workflow without an alert should not be allowed to touch customer data. It is cheaper to add the alert than to explain a month of silence to the owner.
If it is already failing
Start with the cheapest question: when did it last run successfully? Most platforms show this in one click, and the answer is often further back than anyone expected. From there the triage runs in roughly this order.
- Find the last successful run and the first failed one, and write both dates down before you touch anything.
- Read the actual error body rather than the node name. "Request failed with status code 401" and "status code 429" send you to two completely different fixes, and the node name is the same in both.
- Compare durations across the list. Runs that finished far too fast did nothing, and they are sitting there marked as successes.
- Check where errors go, then open that destination yourself. An archived channel, a shared inbox with a rule on it, or an address belonging to somebody who left all count as nowhere.
- Test one credential by hand, outside the workflow, before changing any logic.
On n8n specifically, the triage order when a workflow keeps failing starts with the error body and the date the failures began, for the same reason.
Retries come next. Wrap every outbound call in a retry with backoff and a dead-letter step that stores the failed payload somewhere a person can replay it from. On n8n that is an error workflow and a spreadsheet row. On Make it is an error handler route. On Zapier it is mostly the platform's own replay, which is one of the things the premium pays for.
Configuration is the fix people skip because it feels cosmetic. Pull field names, model names and API versions into one settings block at the top of the workflow, or an environment file for custom code, so that when the CRM renames a field the change is one line instead of a hunt through forty nodes. This is also the cheapest defence against schema drift, since the hunt is what makes drift expensive.
Evals take longer, and building an eval set from your own transcripts is a job of its own. The short version is that every incident above becomes a test case, so the same failure cannot come back quietly.
Ownership is the last one and the hardest to buy. Someone has to be named, in-house or a vendor, with the accounts in the business's name either way, because the failure we see most often after a builder leaves is that nobody can even log in to see what broke.
Not every automation needs all of this. A weekly report that emails a CSV can fail for a week and someone will notice on Monday. Spend the reliability budget on the flows where a quiet failure costs money by Tuesday: lead intake, bookings, invoicing, anything that talks to a customer. In the rescues we have scoped, what killed the system was usually an HTTP 500 with no retry, a credential that expired on a weekend, a payload that changed shape, or the archived channel above.
Whether the answer is a repair or a rebuild is a separate decision, and we have written up how we make it. If a system you rely on is already failing quietly, the $500 written diagnostic finds the cause in three business days and is credited in full against the fix.
More on engineering
Have a system that needs this treatment?