When a Path Stops
Error Handling is organised by mechanism: here are the knobs, here is what each one does. This page is organised the other way round — you saw something, and you want to know what caused it.
Work through it in order. The first three checks account for most of what looks like a broken Task and is not.
Check these three first
Section titled “Check these three first”-
Is the Task’s Status Level hiding the answer? New Tasks default to None, which records nothing at all — a task says nothing unless asked. A deliberate stop, a closed Gate, a rule that is not satisfied, and a verb that resolved a failure are all silent at the default level, same as a real failure would be. A Task that stopped for one of those reasons looks, at the default level, exactly like a Task that did nothing. Raise it to Debug and run again before concluding anything. See Turning the silence off.
-
Is a Gate closed? A connected Gate Input carrying
falseorNilstops the Path at that Node, and it is not a failure: the verb is not consulted and nothing is written, and at the default level nothing is recorded. A Gate wired to a value that isNilbecause it was never written stops that branch every run, silently. -
Did the Node run at all? Two checks run ahead of the Operation and they end differently. A Validation rule that is not satisfied stops the Node: it waits, its dependents do not run this firing, and the log says so at Information — which the default level does not record, so seeing no status does not mean the Operation ran. A value type the Node cannot read fails it, at Error, and the Node’s On Error verb resolves that failure exactly as it resolves one the Operation reports itself.
Symptom table
Section titled “Symptom table”| What you saw | What is responsible | Where to look |
|---|---|---|
| Nothing downstream ran, and there is an Error about a value type | The runtime type check met a type the Node cannot read, and the Node’s On Error is Stop this branch | The named port’s Accepted types; Port type masks |
| Nothing downstream ran, and there is no status at all | A rule that is not satisfied, a closed Gate, a deliberate stop by the Operation, or a verb that carried on — all recorded below the Task’s Status Level | Raise Status Level to Debug; Gate Inputs |
| One branch ran and its sibling did not | A stop reaches only the Nodes that depend on the stopping Node. The sibling does not depend on it, so it is unaffected — this is by design | How Stops Propagate |
| The value downstream is stale — it is last run’s value | Continue with the last value: the Output kept its value and its stamp, so nothing downstream can tell the run happened | Stale versus fresh below |
| The value downstream is the Fallback | Continue with the fallback resolved the failure, writing the Output’s Fallback and stamping it as this run’s value | The Node’s On Error; the port’s Fallback; Stale versus fresh below |
| A downstream Node refuses to run and its own Inputs look fine | Its Input carries A value whose last update succeeded, and the Operation feeding it failed — possibly on a different Path | Cross-Path failure signalling |
| An outbound call failed and nothing downstream of it ran | The Node’s On Error is Stop this branch: the completion fires its Path, and that Path stops at its first Node, which is this Node | Operations that answer later |
| A reaction branch never runs | Its Input carries A value whose last update failed and sits on the same Path as the Node feeding it, which stops its branch on a failure and so never runs its dependents | Per-Port Input Validation |
| My catch did not run | The Node whose error output feeds it did not fail this firing. It stopped — a closed Gate, a rule that is not satisfied, a stop the Operation chose — and a stop is not a failure; or it crashed, which retires the Task, and a retired Task runs nothing, its catches included; or it sits on a Path this firing did not run, and a catch answers only a failure in its own firing | Raise Status Level to Debug; When the catch fires, and when it does not |
| The Task won’t deploy: a Node can never run | It reads from an Output and from the error output of one Node, so it needs that Node to have both delivered and failed in one firing; under Stop this branch that never happens, and the Editor flags it as an Error that blocks the deploy | Feed it from one branch only, join the branches in a Funnel, or change the producer’s On Error verb; Joining back |
| A Task stops firing entirely, with no edit of yours to explain it | A cyclic trigger graph crossed engine.maxFiringDepth, one Trigger asked for more firings in a second than engine.maxFiringsPerSecond allows, or one Trigger had engine.maxPostedPerRunee firings waiting; the Task was retired. The first two leave a Warning naming the Trigger and the cap it crossed; the pending cap is answered as a Task failure, an Error naming the Trigger’s own queue and the cap | Loops |
| The Editor refuses a Task whose Node is set to Continue with the fallback | The Editor refuses the Task: a Node on Continue with the fallback needs a Fallback on every Output it would write | The port’s Fallback; Per-Output Fallback Value |
| Nothing happened at all, and no Path ran | The Trigger did not fire, or the Task is not deployed | The Task’s Trigger; redeploy and check Monitoring |
Stale versus fresh
Section titled “Stale versus fresh”This is the single most confusing consequence of the model, and it explains a Path that stops several Nodes after the one that actually failed.
Every Output carries a value and a write stamp — a note of which run last wrote it. The three verbs differ in what they leave on the Output:
| Verb | The value | The stamp | A downstream A value not used yet check |
|---|---|---|---|
| Stop this branch (default) | Unchanged | Not advanced | No dependent on this Path reads it |
| Continue with the last value | Unchanged | Not advanced | Fails — nothing fresh arrived |
| Continue with the fallback | The Output’s Fallback | Advanced | Passes |
So the two continuing verbs leave the Path running and differ in what a
downstream freshness check sees. Under Continue with the last value a
downstream Input set to A value not used yet stops its own Node — which is
usually what you want, and is also why a failure at one Node surfaces as a stop
at another. A value that exists passes under Continue with the fallback,
which writes; under Continue with the last value it passes only when some
earlier run already wrote the port.
Whichever verb resolves the failure, the Operation’s last attempt reads as failed — so a downstream A value whose last update succeeded check stops regardless of which verb was chosen. That check is the one that sees through all three.
Turning the silence off
Section titled “Turning the silence off”The Task’s Status Level is a single Task-level setting — there is no per-Operation override — and it records every status of the chosen severity or worse. Monitoring has the full ladder against what each level lets through.
Debug is the level to diagnose at. It is the first level at which a verb resolving a failure is recorded, which is exactly the event that turns into a mystery three Nodes later.
What it costs: every recorded status is a message on the wire and a row in Last Statuses. A Task firing at any rate will fill that window quickly at Debug and faster at Trace. Raise it to diagnose, lower it when you are done — a Task left at Trace is noise that hides the next real problem.
What you cannot see
Section titled “What you cannot see”Knowing what the product does not offer stops you looking for it.
- There is no per-Node runtime indicator on the canvas. A Node can carry two marks — a coloured frame and a dot in its top-right corner — and neither is about a run. The frame is the live compile and cell-evaluation state; the dot is the last Verify report’s word about that Node, and it drops off the moment you edit the Node. Both are design-time. The runtime answer is the status feed, and nowhere else.
- There is no “jump to node” from a status row. Last Statuses
is read-only and session-wide; its rows do not locate anything. Where a message
names a place it says so in words —
node index 2 input 1— and you find that Node yourself. Compile-time issues are clickable, in the Editor. - There is no per-cause verb. The verb answers every failure the same way; a rule that is not satisfied is not a failure and never asks it.
Still stuck
Section titled “Still stuck”Raise the Task’s Status Level to Debug, run it once, and read Last Statuses from the bottom up — the earliest entry of the run is the cause, and everything after it is consequence. If the earliest entry names a Node you did not expect, follow that Node’s Inputs back to their sources; a stop propagates forward, so the answer is always upstream of where you noticed it.