← Back to Resources

Blog articles

Why brittle scripts break, and what adapting to exceptions actually requires

A script that has run clean for fourteen months is not proof that the script is robust. It is proof that nothing unusual has happened for fourteen months.

Robustness and an uneventful year look identical from the outside, and the difference between them is where most automation programs quietly go wrong. The script processes the supplier confirmation, reads the date, updates the line, and does it four hundred times a week without a complaint. Then a supplier's system gets upgraded, the confirmation arrives with the quantity split across two lines instead of one, and the script does exactly what it was built to do. It reads the first line. It updates the order with the wrong quantity. It reports success.

Nobody finds out until the delivery arrives short, eleven days later.

Every step in that sequence ran as designed. The script detected the confirmation, wrote to the ERP, and reported success. What it could not do was work out that two lines meant something one line did not, and that is the reasoning step: the second of the four movements of an autonomous workflow we walked through last week, detect, reason, act, verify. This post is the engineering argument underneath it. Not why agentic sounds better than scripted, which is the positioning argument we made in August's buyer's field guide, but what specifically fails in a scripted approach, whether it is badged as RPA, a bot, or a macro somebody wrote in 2019, and what a system has to be able to do instead. If you are the person who has to sign off on something that writes into your ERP, the difference is not philosophical. It shows up in your maintenance backlog.

The short version

         
  • A script encodes the steps of a task. It does not encode what the task is for, which is why it cannot tell a variation from an error.
  •      
  • Scripts fail in three ways, and only one of them is loud. The dangerous failure is the one where the script succeeds against the wrong data.
  •      
  • Adding branches does not solve this. The exception space is long-tailed, so every branch you add covers a smaller slice of what is left.
  •      
  • Adapting to an exception requires four things a script does not have: tolerance for unstructured input, grounding in your business context, the ability to choose among several valid responses, and a controlled write path.
  •      
  • The honest test of any vendor is not whether the system handles the exception you describe. It is what happens on the one you did not.
  •    

What a script actually knows, and what it doesn't

Robotic process automation is not a bad technology. It is a precisely scoped one, and the scope has been narrowing. Not because the tools got worse, but because the conditions they assume, stable formats, stable portals, counterparties who do a thing the same way twice, describe less and less of how the work actually arrives. A script encodes a sequence: open this, read that field, compare it, write it here. It is a recording of how a competent person performed a task on the day the recording was made. That is genuinely useful when the task is stable, high volume, and structurally identical every time. Payroll runs. Standard invoice matching against a fixed template. If the shape never changes, replaying the sequence beats a human on both speed and consistency.

What the recording does not contain is the intent. The script knows that the value in the third column goes into the delivery date field. It does not know that the field represents a promise to a customer, that the promise has a tolerance, that the tolerance is different for one account than another, or that a date moving is sometimes routine and sometimes an escalation. The operator who was recorded knew all of that. None of it was recorded, because none of it was a keystroke. That is not a flaw in the implementation. It is what a recording is.

The three ways a script breaks, and why only one of them is loud

In practice, scripted automation in supply chain execution fails in three distinct modes, and it is worth separating them because they have very different costs.

         
  1. The surface changes. A portal is redesigned, a field moves, a login flow adds a step. The script cannot find what it is looking for and stops. This is the loud failure, and it is the cheap one. Someone gets paged, someone points the script at the field's new location, work resumes. Annoying, visible, bounded.
  2.      
  3. The shape changes. The same information arrives structured differently: a quantity split across two lines, a revision sent as a reply in an existing thread rather than a new message, a date in the body of an email instead of the attached PDF. Sometimes the script halts. Sometimes it finds something that looks close enough.
  4.      
  5. The meaning changes. The input parses cleanly and is wrong to act on. A supplier acknowledges a purchase order and separately notes a partial short in the next paragraph. A carrier posts a status that is technically an update and functionally a missed commitment. The script reads a valid field, writes a valid value, and reports success, and the error only surfaces downstream when the shortfall reaches a customer.
  6.    

The expensive failures are the ones that stay quiet: all of mode three, and the half of mode two that finds something close enough. A script that fails silently is worse than no script at all. Having no automation leaves a known gap that a person covers. Silent failure creates a gap nobody knows exists, behind a green status. By the time it surfaces, the dispute window has closed, the expedite is already booked, or the OTIF deduction has been posted.

This is also the shape of the execution gap we keep coming back to. Roughly 40 to 60% of supply chain execution happens outside the system of record, in email threads, supplier and retailer portals, attached PDFs, and shared inboxes. That is not a data hygiene problem to be cleaned up before automating. It is the medium the work is conducted in, because when reality diverges from the plan a person writes to another person about it, in prose, with an attachment. Scripts were built for the structured half. The exceptions live in the other half, and that gap is where about 2% of annual revenue leaks out, roughly $20M a year for a $1B company.

Why adding more branches does not fix it

The intuitive fix is to handle the new case. The supplier splits quantities across lines, so add a branch for split lines. The revision comes as a thread reply, so add a branch for thread replies. Each fix is small, each one is justified, and each one works.

The problem is the distribution. Exceptions are long-tailed. A handful of exception types account for most of the volume, and then there is a very long tail of cases that each occur a few times a year and collectively account for a large share of the ones that actually hurt. The high-frequency cases get scripted early, because they are the ones anyone notices. What remains is a tail where every additional branch covers a thinner slice of what is left.

So the maintenance curve runs the wrong way. Early branches buy a lot of coverage cheaply. Later branches buy very little at the same cost, and every branch added is another thing that can itself break when a surface changes. Teams running large scripted estates end up spending a substantial and growing share of their engineering time repairing existing automations rather than building new ones, which is the point at which the program stops compounding.

There is a second-order cost that is easier to miss. Every branch is a decision someone made about what the business wants, encoded in a place where nobody can read it back. The reasoning lives in a condition statement written by a contractor two years ago. When the business rule changes, nobody knows which of the four hundred branches encode it. The automation becomes a second, undocumented copy of your operating policy, and it drifts from the real one.

What adapting to an exception actually requires

If the answer is not more branches, it has to be a system that can encounter a case nobody enumerated and still choose defensibly. That is a higher bar than parsing, and it needs four things.

         
  1. Tolerance for unstructured input. The workflow has to read what people actually send: a thread as a thread rather than a message, an attached PDF whose layout changed without notice, the same event phrased three ways by the same supplier in three quarters. Your system of record does not understand unstructured data. Reading it is the entry requirement, not the achievement.
  2.      
  3. Grounding in your business context. Knowing that a ship date moved eleven days is not actionable on its own. Whether it matters depends on what the inbound quantity was promised against, whether coverage exists elsewhere, whether the slip crosses a commitment date, and which customer sits behind the order. None of that is parsing. Our CTO Yotam has written the engineering account of assembling that context in Anatomy of an Enterprise-Ready Agentic Workflow, and the scoping point in it is why this is fundable at all: you need a dozen fields, not a master data program.
  4.      
  5. The ability to choose among several valid responses. This is the actual difference, and it shows up on the second step rather than the first. A script executes the response its author anticipated. A workflow that reasons holds several acceptable responses at once, expedite, source elsewhere, partial-ship, escalate to the account owner, and selects the one that fits this situation against your rules. The test is not whether it gets the common case right. It is whether it produces a defensible answer on a case that was never enumerated.
  6.      
  7. A controlled write path. Adaptation without control is just a faster way to be wrong. Every action needs scoped identity, an approval gate you define, reversibility, and an audit trail covering the draft, the evidence, the gate's decision, and the write. The gate is a per-action setting rather than a switch for the whole workflow: routine changes commit on their own, changes carrying commercial risk wait for the person who owns the relationship. We made the full case for that in The spectrum of autonomy, and it holds here. Human-in-the-loop is what makes adaptation deployable rather than alarming.
  8.    

The fourth point is where the next post in this series picks up: context, guardrails, and how you stay in control of a system that can choose.

Fourteen months without an incident is a real achievement, and it is also the most misleading number in your automation program, because it measures the absence of unusual events rather than your readiness for one. The supplier upgrade is coming. The portal will be redesigned. Someone will split a quantity across two lines. And the one that costs you will not announce itself. It will parse cleanly, report success, and surface eleven days later.

The question worth asking is not whether your automation will encounter something it was not built for. It is what you will be able to do on the morning it does.

There is a cheap way to find out before then. Take the worst exception your team handled last month, the one that needed three people and a phone call, and walk it through what you have running today. Wherever it stops is your answer. We will run that exercise with you against your own stack if that is useful, and if your scripts hold up, that is worth knowing too.

Alison Crawford is Director of Product Marketing at Emerix, the system of action for supply chain execution. She has spent her career in supply chain software, with prior roles at RELEX Solutions, Aera Technology, o9 Solutions, and Kinaxis, and was recognized in the 2023 Women in Supply Chain Awards. She writes about the distance between what supply chain software promises and what it actually executes. Connect with Alison on LinkedIn.

FAQ

Why do RPA scripts break so often in supply chain?

Because they encode the steps of a task without encoding its purpose. A script replays a recorded sequence, so any change to the surface it reads, the structure of the input, or the meaning behind it puts the script outside what it was built for. In supply chain execution that happens constantly, because much of the work arrives as email, PDFs, and portal updates that change without notice.

What is the difference between a script failing loudly and failing silently?

A loud failure is one where the script cannot find what it expects and stops, which gets noticed and fixed. A silent failure is one where the input parses cleanly but is wrong to act on, so the script completes successfully against bad data. Silent failures are more expensive because the error surfaces downstream, often after a dispute window or a commitment date has passed.

Can't you just add more rules to handle new exceptions?

You can, and for the highest-volume exception types it is worth doing. The limit is that exceptions are long-tailed, so each additional branch covers a thinner slice of what remains while adding another component that can break. Past a certain point, maintaining the branches consumes the capacity that was supposed to go into new automation.

What does a system need in order to adapt to an exception it was not built for?

Four things: it has to read unstructured input, understand the business context that makes a given event significant, choose among several valid responses rather than execute one predetermined response, and write back through a controlled path with an approval gate and an audit trail.

Does adapting to exceptions mean the system acts without human oversight?

No. Where the line sits between the workflow acting alone and a person confirming first is a setting your team configures per action type, and it moves as trust is earned. Routine changes commit on their own, while changes carrying commercial risk wait for the person who owns the relationship.