Govern5 min read

How much a dry run actually proves before you trust it live

You are about to let a workflow touch something real for the first time, and Workflow Health reports it clean. Before you trust that result, it helps to know exactly what earned it.

The OCNORA team · · updated

Reviewed on · Reviewed by OCNORA engineering

Two different questions, two different checks

“Will this workflow run?” and “will this workflow do the right thing?” sound like the same question asked twice. They are not, and Workflow Health approaches them with different mechanisms because much of the first can be checked from the graph alone and the second cannot.

The first question is about structure: is the expression syntax valid, is every required setting filled in, does every reference point at a node that exists. Much of that can be checked by reading the graph, so it is checked on save, before anything executes. The second question is about meaning: given real data, does the workflow do what you actually wanted. Reading the graph cannot answer that, and neither, on its own, can a dry run — which is the part worth being precise about before you trust one.

The checks that run before you ever click run

Every node in OCNORA is generated from a schema that sets its typed inputs, defaults and validation. On every save and publish, Workflow Health checks each node in the graph against that schema.

  • An expression with a syntax error, or one that points at a node that does not exist.
  • A required setting left empty.
  • An edge that does not make sense where it is drawn.

Nothing runs during this check — it compares the graph against the node schemas. It is aimed at the class of mistake you make while dragging nodes around: a typo in a field name, a branch you forgot to wire up. It cannot catch a mistake that only shows up once real data arrives, because there is no real data yet.

What a dry run adds

Workflow Health adds two checks that narrow that gap. Pre-flight exercises each connection with a harmless call. The dry run then executes the graph with side effects suppressed, so you see the shape of each step’s output before the first real trigger.

That pairing, live connections checked and side effects suppressed, is what makes the step useful rather than theoretical. A token that expired last week, a revoked key, a scope your app never granted: none of those show up in a static check, because a static check never talks to the endpoint. Pre-flight does, and the dry run shows you the shape each step produces. Treat that shape as a good sample, not a promise — a live record can still carry a value the dry run never saw.

What a dry run cannot prove

A dry run that finishes clean tells you the checks found no structural problem and the steps it executed produced output of the expected shape. It says nothing about the side effect it suppressed. If the filter condition is backwards and the workflow would email the customers who did not churn instead of the ones who did, a dry run will not flag that — the filter evaluates without error either way, and the node it feeds was never asked to send anything.

That gap is not a defect in the dry run; it is a description of what suppressing side effects necessarily costs you. You cannot both hold back the write and observe its outcome. Trading one for the other is the entire point — it lets you look at everything up to the write without risking the write itself — but it means the thing you most want to know, whether the write would have been correct, is the one thing a dry run structurally cannot tell you.

So when a dry run passes, the honest status is narrower: the checks found no broken reference, pre-flight reached each connection, and on this run the data had the shape the workflow expects. Whether that data, run through that logic, produces the outcome you intended is still an open question — one only a person reading real output can close.

Closing the gap a dry run leaves open

The check that answers the semantic question is a live run on one record, watched. Not a sample, one: the workflow does the thing it was built to do, on a single real case, and somebody reads the result before the second record runs. If it sends an email, send it to yourself first. If it writes to a CRM, write to a record made for the purpose.

For a step that stays risky after that first run, put a person in the path permanently rather than trusting a clean history. A human approval step parks the run and shows a person the exact payload before it goes out — the refund, the deletion, the message — and waits for a decision. It costs a few minutes on the runs that matter and nothing on the runs that do not.

Reading a clean health check correctly

None of this makes a dry run less worth running. Together with validation and pre-flight it catches much of a whole category of failure — the expired token, the missing scope, the reference to a node that does not exist — before it can reach a customer, and it runs on every save. The mistake is reading a clean dry run as a verdict on the workflow’s judgement rather than on its plumbing.

Starting from a template does not remove this step, it just moves you past the plumbing faster: templates install as drafts, already validated against the node registry, so the first check you actually need to do by hand is the one no machine can do for you — watching the one real record.

See a workflow run on your own use case.

Book a technical demo. Bring an n8n file or pick a template, and we build it with you on the canvas while Workflow Health checks it before it ever runs.