The screen said success. The record said something else.
The screen says finished, the database says running, the error names the wrong cause. Why status and record disagree, and which one to trust.

It is Thursday afternoon. A customer asks why the order they placed on Monday was never confirmed. Someone opens the workflow tool. Monday's run is there, marked finished. Someone else opens the database behind it. The same run is still "running", with no end time.
Two parts of one system are telling two different stories about the same afternoon. Before anyone can fix the customer's order, the team has to decide which story to believe.
Three reports, three kinds of disagreement
This is not rare, and it does not need a broken tool. Three reports from the research behind this series show three different ways it happens.
The screen and the database. One team that runs a workflow tool on its own server reported this. With the setting to not save successful runs switched on, runs finished normally on the screen, while their database record stayed "running", marked as not finished, with no stop time. Those records piled up for every workflow, even a simple one. The reporter put the point precisely: "do not save" should skip the run's data, not the step that closes the run record. When we read the report, the vendor had not confirmed it, and the issue was still open.
The caller and the run. Another team reported a production workflow that answered customers in a chat app through a webhook. Some runs stayed "running" for ever, with no error and no time-out, while the webhook had already answered that all was well. The stored record was empty; it did not even show what the first step received. Only a restart cleared it, so the team built a watchdog that restarted the container when a run sat stuck. Weeks later the reporter found the cause, and it was their own: a credential moved from an old server still held an old password, and the client behind one step retried for ever. So the step never failed and wrote nothing. With progress saving off, which was the default, the stored run showed only its first snapshot, no matter where it had really stopped. Once progress saving and more detailed debug output were switched on, the stuck step was named at once.
The error and the cause. A developer reported that their hosted agent, called from their own web app, suddenly returned an error saying an internal error had occurred, and the app showed a server error. It had always worked, and nothing had been changed. The developer could not tell whether the fault was in their own code or on the vendor's server. A forum expert first explained that the error line only showed where the failure came to the surface, not its cause, and that the server error came from the developer's own app. When the developer shared the trace of the run, the expert found the cause: the model provider's per-minute token limit. The developer did not reply to confirm.
Three reports, one pattern. Each status was written by one part of the system, at one moment. The truth was in the step-by-step record, when the record had kept it.
Why a status and a record drift apart
A status is one field. Something writes it once or twice: when the run starts, and when some part of the system decides the run is over. A record is many entries, written as each step starts, receives, returns or fails.
Different parts of the system write them, at different times. So they can disagree in both directions.
- The status can say "finished" because the screen saw the last step end, while the write that closes the record never happened.
- The status can say "running" for ever because no step ever failed, while the run is stuck on one step that will never end.
- The error text can name the place where a failure came to the surface, while the cause sits two layers down.
- And a run can end "finished" while one step recorded an error, because the flow was built to catch that error and carry on. That is not a fault at all. It is a design choice, and you need to be able to see it.
The record also depends on its own settings. A record that keeps only the first snapshot, or nothing for successful runs, tells you less than you think. Find out what yours keeps by default, before you need it.
Which one to believe
One simple rule helps: believe the entry written closest to the step.
The status is a claim about the run. The step entries are the evidence: this step started, it received this, it returned that, or it failed with this error. When the two disagree, the evidence wins, and the disagreement itself is a finding. Write it down. It tells you which part of your setup cannot be trusted on its own.
If a tool gives you only the status, you have no disagreement to resolve. You have a claim with no evidence behind it.
That record is written by the harness, the layer around the model that runs your agents. Who checks that this layer writes the truth is a question of its own; see who audits the harness.
Where the truth sits in EpicStaff
EpicStaff flows are built from separate steps (nodes), and EpicStaff calls a run a session. Each node writes separate records: a start record with its input, a finish record with its output and state, and an error record with the details. Each has a node name, an order and a timestamp, and they are kept apart from the session status. The live screen can briefly lag behind; the stored run record is the source of truth.
A run can end "finished" with one node's error on file. A decision-table node catches its own error, writes the error record, routes to its error path or to the end, and the run carries on. Most other nodes pass the error on instead. You see the node error in the run's message view. You also see it in the all-sessions "error cause" filter, which finds any session with an error record, whatever its status.
The session export (JSON) holds the per-step record, including tool calls: each agent tool call and each tool result is its own record. Tool arguments and tool results are cut off at 2,000 characters each, and marked as cut; they are never summarised.
For what a useful run record holds, see The agent finished. Nobody can say what it did.
A short check each week
Three questions, once a week, for the flows that matter. They work on any platform; the EpicStaff note shows where to look in ours.
- Which runs have an error on file, whatever their status? Do not filter on "failed" alone. A finished run with a step error is the run nobody looks at. In EpicStaff, the all-sessions "error cause" filter finds any session with an error record, whatever its status.
- Which runs still say "running" long after they should have ended? For each one, open the record and find the last step that started. That step is where to look, not the run as a whole. In EpicStaff, the record shows the last step that started, even when a run hangs.
- Do a few finished runs match the system they were meant to change? Pick three. Check the order, the email or the record in the target system. A status cannot tell you that; only the target system can. For runs that end green with the work not done, see A green tick is not a finished job.
And once, not every week: find out what your tool's record keeps by default, and what any "do not save" or "save less" setting really skips. Add that question to the questions to ask any vendor before you self-host. Do it on a quiet day, not in the middle of an incident.
When the screen and the record disagree, that is not noise. It is the first clue.


