FlowDrop Docs

Edge structure

The JSON format for workflow edges — connections between nodes, handle IDs, and edge categories.

Every item in a workflow's edges array is a WorkflowEdge. It represents a connection between an output port on one node and an input port on another.

Schema

interface WorkflowEdge {
  id: string;
  source: string;
  target: string;
  sourceHandle?: string;
  targetHandle?: string;
  type?: ConnectionLineType;
  selectable?: boolean;
  deletable?: boolean;
  data?: {
    label?: string;
    condition?: string;
    metadata?: {
      edgeType?: EdgeCategory;
      sourcePortDataType?: string;
    };
  };
}
FieldTypeRequiredDescription
idstringYesUnique edge identifier (e.g., "e-loader-analyzer").
sourcestringYesID of the source node.
targetstringYesID of the target node.
sourceHandlestringNoID of the specific output port. See Handle IDs.
targetHandlestringNoID of the specific input port. See Handle IDs.
selectablebooleanNoWhether the edge can be selected in the editor.
deletablebooleanNoWhether the edge can be deleted by the user.
data.labelstringNoDisplay label on the edge.
data.conditionstringNoCondition expression (used with gateway branches).
data.metadata.edgeTypeEdgeCategoryNoVisual styling category.
data.metadata.sourcePortDataTypestringNoData type of the source output port.

Handle IDs

Port handles follow a deterministic naming pattern:

{nodeId}-{direction}-{portId}

For example:

  • content_loader.1-output-items — the "items" output port on node content_loader.1
  • analyzer.1-input-content — the "content" input port on node analyzer.1
  • router.1-output-high — the "high" branch output on a gateway node

This format lets FlowDrop map edges back to specific ports during rendering and execution.

Edge Categories

The edgeType field controls the visual style of the edge on the canvas:

CategoryVisual StyleWhen Used
dataSolid gray lineDefault — general data flow between nodes.
triggerSolid line with trigger colorControl flow connections (port dataType: "trigger").
toolDashed amber lineTool interface connections (port dataType: "tool").
loopbackDashed gray lineLoop iteration connections (targets a loop_back port).

The editor sets edgeType automatically based on the source port's data type. You generally don't need to set it manually in JSON.

Unknown edge types are refused at save

This is a different field from the styling category above. The editor writes its visual category at data.metadata.edgeType; a server reads the edge's semantic type from data.edgeType, one level up, and falls back to the target handle when it is absent. The styling category is never validated.

A server implementation may refuse a semantic data.edgeType it does not recognise. The Drupal server does: a non-empty string there that is not one of the values it knows fails validation with the code R14_EDGE_TYPE_UNKNOWN at the locator edge.{index}, where {index} is the edge's position in the edges array.

The values the Drupal server knows are data, trigger, tool_availability, loopback and agent_result.

Absent, empty and non-string declarations are deliberately untouched: they are not typos, and the handle-based classification they fall back to is the intended default. The rule exists for the value that looks deliberate and is wrong — a loopbak silently becomes an ordering edge in the compiled graph, and if it was meant as a loopback it hard-errors much later as a forward cycle, naming the cycle rather than the typo.

The check is save-only. The read path is unchanged, so a workflow already stored with an unrecognised value still loads, compiles and runs. Launching one is explicitly not blocked: the launcher re-validates every stored definition before running it — a definition can reach storage without passing the save path — and this rule is excluded from that gate. Bundle import and workflow migration do enforce it; both are writes.

To find stored workflows carrying a bad value, run the Workflow Doctor against them (Administration › FlowDrop › Workflows, then Doctor on the workflow). It reports the condition on an already-stored workflow, where a save would refuse it.

Examples

Data Edge

A simple data connection between two ports:

{
  "id": "e-loader-analyzer",
  "source": "content_loader.1",
  "target": "analyzer.1",
  "sourceHandle": "content_loader.1-output-items",
  "targetHandle": "analyzer.1-input-content"
}

Trigger Edge

A control-flow connection that triggers execution:

{
  "id": "e-start-loader",
  "source": "start.1",
  "target": "content_loader.1",
  "sourceHandle": "start.1-output-trigger",
  "targetHandle": "content_loader.1-input-trigger",
  "data": {
    "metadata": {
      "edgeType": "trigger",
      "sourcePortDataType": "trigger"
    }
  }
}

Tool Edge

A dashed connection linking an agent to a tool:

{
  "id": "e-agent-tool",
  "source": "search_tool.1",
  "target": "agent.1",
  "sourceHandle": "search_tool.1-output-tool",
  "targetHandle": "agent.1-input-tool",
  "data": {
    "metadata": {
      "edgeType": "tool",
      "sourcePortDataType": "tool"
    }
  }
}

Gateway Branch Edge

A conditional edge from a gateway branch:

{
  "id": "e-router-high",
  "source": "router.1",
  "target": "urgent_handler.1",
  "sourceHandle": "router.1-output-high",
  "targetHandle": "urgent_handler.1-input-input",
  "data": {
    "condition": "priority > 8",
    "metadata": {
      "edgeType": "data"
    }
  }
}

Connection Validation

The editor validates connections automatically before creating edges:

  • Type compatibility — only compatible port data types can connect
  • Cycle detection — prevents circular dependencies (O(V+E) algorithm)
  • Loopback prevention — nodes cannot connect to themselves

For more on data type compatibility rules, see Port System & Data Types.

Next Steps

On this page