Flow rules
A flow is checked in three places, and each one refuses a different class of problem. The canvas refuses an edge as you draw it. A save refuses a graph the runtime cannot execute. Run checks refuse a graph that would run and not do what it looks like it does.
What the canvas refuses
Each edge is judged on its own as you draw it.
- The pair of nodes. A Target must be preceded by a Transform. A DB Script can only feed a Source or another DB Script. Notification is a terminal node.
- The pair of ports. A port that carries rows cannot feed a port that expects a
signal. This is what separates
Start > Fork > Sourcefrom a Fork splitting rows, which the node types alone cannot tell apart. - Container boundaries. An edge cannot cross into or out of a Loop container body.
Connect to the container's
inport instead.
An edge that a saved flow already contains and the rules do not allow is drawn as a dashed red line with the reason on it. Nothing is removed from your flow.
What Start can connect to
A Source, a DB Script, a Webhook Trigger, a Fork, a Sub-workflow, a Notification, a Variable, a Cache or a Data Profile.
Start sends no rows, so it cannot connect to a step that reads rows, such as a Transform or a Log. To begin a transform chain, put a Source first.
Variable, Cache and Data Profile are context setters: they prepare values the rest of the run reads rather than passing rows along an edge. Put one on Start to prepare a run before any Source reads.
What a save refuses
- A loop in the graph. Two nodes that feed each other, directly or through a chain. A loop has no order to run in, so the message names the nodes involved and you remove one edge to break it. Use a Loop container to repeat work.
- Anything other than one Start. A flow has exactly one Start, at the top level. A Start inside a Loop container body does not count.
Everything else saves, including a half-wired step, a Target set to one side, or a port not connected yet.
What run checks refuse
Run checks open before a run starts and list everything that would stop the flow doing what it says.
- Missing connection, action or field mapping on a node.
- An input port with no edge, so rows arrive from nowhere.
- A Message or Loop container feeding a Target with no Transform anywhere before it. A Target needs mapped fields. For a Loop container, a Transform inside the body counts.
- A Fork whose mode does not match its input: a Fork launched by Start can only fan out to Sources, and a Fork that copies rows cannot feed a Source.
- A Start that launches a Webhook Trigger and something else. The flow runs once per inbound delivery, so a Source on the same Start is read again every time.
- An Approval decision port that goes nowhere.
- A Node Call outside a Loop container body, an empty Loop container, or containers nested more than three deep.
A node that is not connected to Start is not checked at all, so you can keep drafts on the canvas beside a working flow. A flow with nothing connected to Start does not run.
If the run monitor reports "This run could not be found.", the run was accepted but never started. It stops checking, and you can start the run again.
Start is always there
Start cannot be deleted, and it has no Delete button. A saved flow that opens without one has a Start added, and you are told so. Nothing else in your flow is changed for you.
When two edges land on the same port
Most input ports take one edge. Where two arrive, the rows are combined with no column rules applied, and you are told when the data pipeline opens. Use a Union node to merge two streams and choose how mismatched columns are handled.
Two ports accept many edges by design: Start's out, so one Start can drive several
Sources, and Union's in.