Entry and exit
A graph has two boundaries: entry, where the request arrives, and exit, where the answer leaves. Both obey strict rules — breaking them used to fail quietly, throwing half the work away rather than stopping the run.
Exactly one entry
An entry is the run’s input, not a start marker. The engine parses the same input object for every entry node, so a second one cannot carry a second input: it duplicates the first and starts a second branch that is synchronised with nothing. Both chains run in full, and both are billed.
Two entries are therefore the graph.multiple_entry error. It is unconditional:
there is no draft state in which two entries lead to something valid. The error
does not stop you from saving the graph, but it does block deploy and run.
The editor will not let you create a second entry: dropping one from the palette is ignored when the canvas already has an entry, and when you paste a ready-made snippet its entry is mapped onto the existing one — every edge from it lands on the real entry.
The entry’s two outputs
output— the message. For chat, Telegram and webhooks this is a string with no fields. When the run was started with an arbitrary JSON object (a manual run, the API, a call from another workflow), it is that whole object.data— the trigger context, a fixed shape:trigger,workflow_id,execution_id,workspace_id,user_id,chat.session_idand thetelegram/webhook/cronblocks.
At least one exit, and it has to be reachable
A graph with no exit gets the graph.no_exit warning. The worse case is an exit
that exists but is reached by no exec or execute_data edge. Such an exit never
runs, and the execution ends with an empty result — the validator rejects it with
exec.exit_no_exec_trigger.
A template reference does not start a node: {{ nodes.<id>.output }} reads a value
but never makes the exit fire.
What the exit does
- The
endport takes the final value. The Output Expression (output_mapping) field, when non-empty, replaces whatever arrived onend. - A separate
filesinput takes file references, and they leave together with the answer: images, audio and attachments are shown next to the chat message. - The Error message (
error_text) field sets the text a user sees after an unhandled failure.error(a short, safe description of the failure),error_code,error_id(the reference code for support),failed_node_idandfailed_node_typeare available inside it. Technical detail — a provider’s reply, the text of a database query — is not, at any setting: this message is read by the person talking to your workflow, not by you. The full picture stays in the node card and the run logs.
Several exits: only for mutually exclusive branches
Every exit that ran writes into one and the same result object. The winner is not the one that finished last, but the last one in the order the nodes are listed in the graph definition — reordering that list changes the answer. In chat the rule is different: the exit that started streaming first is the one shown, and the other one’s tokens go nowhere.
Two exits that can fire in the same run are therefore exec.multi_exit_race: an
error at deploy and run, a warning while you are still editing.
- Execute + Data
How to fix the race
Merge the branches into one exit. If they genuinely run in parallel, put a
wait_all in front of it and wire every branch into its
barrier_in handle. Giving each parallel branch its own exit is not a way out —
that is precisely the shape in which one answer overwrites the other.