The automation that worries me is not the one that crashes. A crash stops the run, someone sees it, and the damage stays small. The one that worries me keeps running, every execution shows a green check, and the records it writes have been wrong for weeks.
That is a silent failure: the workflow completes, nothing reports an error, and the output is wrong, empty or written to the wrong place. It is usually found by a customer, a colleague or a report that no longer adds up.
AI steps make this more common, because a model almost always returns something. An empty input becomes a confident summary, and a renamed field becomes a plausible guess. This article covers where silent failures hide, why the run history will not show them, and the order I use to diagnose one.
01
What a silent failure is
A workflow run answers one question: did every step finish without throwing an error? A silent failure is a run where the answer is yes and the work is still wrong.
That gap exists because the workflow engine judges execution, not meaning. An API call that returns 200, a model step that returns valid JSON and a database write that succeeds all count as success, even when the JSON describes the wrong document and the write lands on the wrong record.
With a deterministic script, a bad input usually breaks something visible. With a model in the chain, a bad input is often absorbed. The model fills the gap with something that looks right, and the next step accepts it because its shape is correct.
02
Where silent failures hide
When an automation that worked for months starts producing wrong data, the cause is usually one of these:
- An upstream field was renamed, moved or emptied, and the workflow treats the missing value as blank instead of stopping.
- An API answers with a success status and an error message in the body, and nothing reads the body.
- A step is set to continue on error, so it passes nothing downstream and the run still completes.
- A model step changed behavior after a provider update or a prompt edit, and its output still parses, so no check notices.
- A filter or branch condition stopped matching, so a whole path quietly stopped running.
- The trigger stopped firing, so there is no run left to fail.
- A retry repeated a write, or a write landed on the wrong record, and the confirmation came back correct.
None of these produce an error in the run history. Each one changes the output while every step still reports success.
03
Why the run history will not show it
The first instinct is to open the execution log and look for red. For a silent failure that wastes time, because the log records what ran, not whether the result was right.
The evidence lives in the output: the records the workflow wrote, the messages it sent and the values it changed. A silent failure is found by comparing that output with the source it should match, and the comparison is the part most workflows never do.
That is also why these failures last so long. The monitoring watches for errors, and a silent failure does not produce one.
04
How I diagnose a silent failure
When I review a workflow that produces wrong data, I work from the output backwards, in this order:
- Start from one concrete wrong result that a person noticed, and name the source of truth it should have matched.
- Pull a small sample of recent finished records and compare each one with that source, reading whole records rather than single fields, because many defects only show in the relationship between fields.
- Walk one wrong record backwards through the steps and find the first boundary where the value is already wrong.
- Classify the fault at that boundary: changed input, coordination (order, state, retries), a model step, or the final write.
- Find when it started, and compare that date with upstream changes, prompt or model changes, workflow edits and expired credentials.
- Fix it at that boundary with a deterministic check, such as a schema check, a required-field rule or a read-back, rather than a longer prompt.
- Turn the record that exposed the failure into a permanent test case, so the same fault fails loudly next time.
The order matters. Starting from the logs or from the model leads to guesses. Starting from one wrong record and its source of truth leads to the step that actually broke, which is usually not the step people suspected.
Read what belongs in the deterministic layer. Validation, state, retries, idempotency and approvals are rules, so code should own them and fail loudly when they break.
05
Checks that make the next failure loud
Diagnosis fixes the failure in front of you. These checks turn the next one into an error someone sees:
- Validate every structured model output before the next step uses it, and stop the run on a missing or out-of-range value.
- Assert on output, not only on run status: a plausible record count for the run and a fill rate for every field a later step depends on.
- Read back what the destination actually accepted after each important write, instead of trusting the confirmation.
- Send a heartbeat to something outside the workflow, so a trigger that stops firing raises an alert from its absence.
- Keep a few known-answer cases, including deliberately bad inputs, and run them after every change to a prompt, model or step.
- Route every error branch to a person or a quarantine queue. A branch that ends silently is a bug.
- Record a failed check as not measured, never as a result, so a broken verifier cannot pass bad work.
In the synthetic construction diagnostic I published, the test set was declared before the run: 56 cases, including 16 known-bad inputs (wrong projects, invalid references, injected instructions) and 8 permission and recovery cases (approval denial, timeout, duplicate, stop, fallback). The company and documents are fictional. The point is the method: the cases that should stop the workflow are tested as seriously as the cases that should pass.
See the 56-case synthetic diagnostic. Representative, edge, known-bad, permission and recovery cases, predeclared before the run. Fictional company, executed method.
06
Fix in place or rebuild?
Teams that inherit a tangle of undocumented automations often assume they have to start over. Usually they do not. Most silent failures sit at a few boundaries, and adding checks there makes the existing workflow trustworthy again.
A rebuild is the better call when the diagnosis shows that:
- Nobody can name the source of truth, so there is nothing to compare the output against.
- Several workflows write the same records and overwrite each other.
- The order of steps and the state live inside a model’s decisions, so a fault cannot be traced to one step.
- Every fix creates a new failure somewhere else.
In both cases, the first step is the same: one workflow, one wrong record, one source of truth. If you want an outside review of a workflow that has started producing wrong data, the hire page explains how I work on AI agent and automation projects.
Read how to keep orchestration in code. When code owns the order, state and retries, a failure can be traced to one step and one decision.