Graph validation codes
The Validate button in the editor runs the graph through the same validator that guards running and publishing. Every finding carries a code — that is what to search for.
Severity depends on what you are doing
The same rule can be advice in the editor and a refusal at deploy. A draft is allowed to be unfinished: you are still drawing the graph, and complaining about every unwired port would be noise. A graph about to go live, though, has to be runnable, so some rules escalate at that boundary.
Such codes are marked “depends” in the table. If you see a warning with one of them, treat it as an error — at deploy it becomes one.
The full list
| Code | Severity | Meaning |
|---|---|---|
array.input_shape | warning | The iteration shell receives something other than an array. |
composite.in_count | error | Wrong number of input boundaries in a composite. |
composite.no_subgraph | error | A composite node has an empty body. |
composite.out_count | error | Wrong number of output boundaries in a composite. |
config.unknown_field | warning | The configuration carries a field the node's schema does not declare. |
exec.exit_no_exec_trigger | error | Nothing triggers the exit node. |
exec.multi_exit_race | depends | Several exits can run in one execution and overwrite each other's result. |
exec.no_execution_edges | depends | The graph has no execution edges — there is nothing to run. |
graph.barrier_unsatisfiable | error | A barrier waits on a branch that comes out of itself. |
graph.cycle | error | A cycle in the execution edges — the scheduler will not run this graph. |
graph.multiple_entry | error | The graph has more than one entry node — the second duplicates the same work. |
graph.no_entry | warning | The graph has no entry node. |
graph.no_exit | warning | The graph has no exit node. |
llm.no_link | error | The node expects a model but no link_llm edge is attached. |
llm.parent_chain | error | A sub-agent inherits its model from a parent, but the parent chain does not resolve. |
node.config_invalid | depends | The node's configuration fails its own validation. |
node.not_activated | warning | Nothing activates the node — it will never run. |
port_type.mismatch | warning | Port payload types differ; the value will be coerced or lost. |
ref.undefined_var | warning | A template references a variable that is not declared. |
ref.unknown_node | warning | A template references a node that is not in the graph. |
struct.bad_node_id | error | A node id is not valid. |
struct.duplicate_edge_id | error | Two edges share an id. |
struct.duplicate_node_id | error | Two nodes share an id. |
struct.edge_bad_channel | error | An edge declares an invalid channel. |
struct.edge_dangling_source | error | An edge starts at a node that does not exist. |
struct.edge_dangling_target | error | An edge ends at a node that does not exist. |
struct.edge_missing_type | error | An edge has no wire type. |
struct.edge_unknown_type | error | An edge names an unknown wire type. |
struct.missing_node_id | error | A node has no id. |
struct.schema_version | error | Unsupported graph schema version. |
subgraph.missing_entry_edge | error | The subgraph has no edge from its entry boundary. |
subgraph.missing_exit_edge | error | The subgraph has no edge to its exit boundary. |
subgraph.nested_iteration_shell | error | An iteration shell is nested inside another where that is not supported. |
var.duplicate_name | error | Two variables share a name. |
wire.andjoin_partial_payload | warning | Mutually exclusive branches meet at one port: only one value will arrive. |
wire.annotation_edge | warning | The edge ends on a note: it has no ports, so the edge carries nothing and is dropped before the run. |
wire.concurrent_stream_merge | warning | Two concurrent streams write into one reply and will interleave. |
wire.fanin_ambiguous | error | Several values arrive at one port with no defined order. |
wire.fanin_needs_barrier | error | Branches can run in the same execution and race for the port — a wait_all is needed. |
wire.handle_name_split_suffix | warning | A port name ends in _exec/_data and collides with split-port aliases. |
wire.on_error_disabled | error | An error branch is drawn while the node's error output is off. |
wire.on_error_not_exposed | error | The node has no error output — enable expose_error_output. |
wire.on_error_payload_type_mismatch | warning | The error branch expects a different payload type. |
wire.port_incompatible | error | The ports are incompatible by wire type. |
wire.port_not_accepted | error | The target port does not accept this payload type. |
wire.required_port_not_wired | depends | A required port has nothing wired into it. |
wire.resource_no_source | depends | The node has no source for a resource (knowledge base, connection): neither a port nor a config field. |
wire.source_handle_missing | error | An edge leaves a port the node does not have. |
wire.stream_swallowed_by_barrier | warning | A token stream hits a barrier and never reaches the chat. |
wire.streaming_fanout | error | A token stream is forked to several consumers. |
wire.target_handle_missing | error | An edge targets a port the node does not have under its current configuration. |
What next
- Execution order — why “node not activated” is possible at all.
- Graph boundaries — about
graph.multiple_entryandexec.multi_exit_race. - Wires — port compatibility and the
wire.*codes.