Debug a run that failed
A run stopped somewhere and you do not know why. This is the order to work in — it goes from cheapest to most invasive, and most failures are identified in the first two steps.
1. Read the code, not the sentence
The run reports a stable error code. Look it up in Error codes before theorising. Three codes account for most confusion:
| Code | What it actually means |
|---|---|
TRANSITION_NOT_FOUND | A node returned a route with no edge wired. The node worked; your graph has a hole |
MAX_NODE_EXECUTIONS_EXCEEDED | A loop ran more nodes than the guardrail allows. Nothing is broken — the cap is too low, or the loop does not exit |
MAX_CONSECUTIVE_FAILURES_EXCEEDED | Something failed repeatedly with nothing succeeding in between. Detection "not founds" do not cause this — look for an action node |
2. Find the last node that ran
The run log names it. That node is where you start — but be careful about which node you blame:
- If the last node is a detection, it very often did its job. A
Find Imagethat finds nothing reports statussuccessand routes to Failure. If Failure is unwired, the run dies withTRANSITION_NOT_FOUNDat the detection — and the detection is not the bug. See status versus route. - If the last node is an action, look at what the screen was at that moment. That is step 3.
3. Turn on Run Evidence and reproduce
Run Evidence captures a screenshot before the flow, after every UI action, and on completion. It is the single most useful debugging tool in the product, because it replaces guessing about the screen with looking at it.
- On the Instance Dashboard, set Evidence Folder….
- Enable Run Evidence on one instance only — not the whole pool.
- Re-run, then open the images from View Logs / Activity Logs.
Look at the frame before the failing action. Nine times out of ten one of these is true:
- The app was not on the screen the flow assumed.
- A popup was covering the target.
- The action fired before the previous screen finished animating — the frame proves it.
Evidence writes one image per action. A long flow with evidence on produces a very large folder. Enable it while diagnosing, disable it for operational runs.
4. Step through the decision with Debug Mode
If the question is "why did it take that branch?", stop reading and watch it.
Right-click a node → Add debug breakpoint, then turn on Debug Mode. The run pauses at your breakpoints and you advance one node at a time, watching the Execution panel report Current Node, Elapsed, Duration, and for OCR nodes the Extracted variables.
Set breakpoints around the part you distrust. Debug Mode with no breakpoints pauses at every node, which is deliberate but painfully slow on a long flow.
5. Isolate the node with Test Node
Once you suspect a specific node, test it alone. Test Node runs just that node against the attached instance and Test Result shows what happened.
This is where perceptual problems get settled with a number instead of an opinion:
| Node | What Test Node tells you |
|---|---|
| Find Image | The real confidence. If your best score is 0.62 against a 0.88 threshold, the template is the problem — not the threshold |
| Read Text | The raw OCR and the extracted variables. If the raw text is wrong, the region or content type is wrong — not your pattern |
| Check Region | The measured value against expected and tolerance |
6. When Test Node passes but the flow still fails
This is the classic case, and it has two usual causes:
The node's source is not upstream on the executed path. A Click whose coordinate source is a Find Image node only works if that Find Image actually ran on this path. Copy-pasted nodes hit this constantly — the setting copies, the relationship does not. The code is COORDINATE_SOURCE_UNAVAILABLE.
A verification read the pre-action frame. The action fired, the verification ran before the screen changed, and it read the old state. Add a settle Wait between them — and give it a Reason, so six months from now you know why that number exists.
Test Node runs a node in isolation; Test Flow runs it in context. When they disagree, the context is the bug.
7. Reproduce it on demand
An intermittent failure you cannot trigger is a failure you cannot fix. Use the Practice App to force the exact state:
dashboard.html?popup=1— the popup is theredashboard.html— it is not?gold=0— the not-enough branch?gap=40— a different slider distance
Pinning the state turns "it fails sometimes" into a test you can run twice.
Checklist
- Looked up the code in Error codes
- Identified the last node that ran — and asked whether it is the culprit or just the location
- Checked whether the failing route is simply unwired
- Looked at the Run Evidence frame before the failure
- Ran Test Node on the suspect and read the real number
- Confirmed the node's sources are upstream on the path it actually took
- Reproduced it with pinned Practice App values
Related pages
- Error codes — every code, with what to do
- Testing and Validation — Validate vs Test Node vs Test Flow
- Retry and Failures — once you know what breaks, choose the right tool
- Execution Model — what the runtime was doing when it stopped