This page explains how Langflow's frontend validates connections between node ports on the ReactFlow canvas. It covers the type compatibility rules, handle serialization format, edge lifecycle cleanup, and where these checks are integrated into the rendering pipeline.
For a description of how nodes render their ports visually, see the GenericNode page (5.3). For how the flow store manages edge state, see State Management (5.5). For how builds consume graph edges, see the Build and Execution Flow (5.6).
Every port on a node is represented by a handle — a typed connector on the left (input) or right (output) side of a node. ReactFlow identifies handles by string IDs. Langflow encodes full type metadata into these strings by JSON-serializing a typed object and escaping it.
The two handle types are defined in src/frontend/src/types/flow/index.ts97-115
| Property | Present on | Description |
|---|---|---|
dataType | sourceHandleType | The component type string (e.g., "ChatInput") |
output_types | sourceHandleType | List of types this output can produce |
name | sourceHandleType | Output field name |
id | both | Node ID |
inputTypes | targetHandleType | List of accepted incoming types |
type | targetHandleType | Raw template field type |
fieldName | targetHandleType | Key in the node's template object |
output_types | targetHandleType (loop only) | Non-null signals this is a loop input |
proxy | targetHandleType (optional) | For proxied fields inside group nodes |
Serialization uses scapedJSONStringfy and deserialization uses scapeJSONParse, both defined in src/frontend/src/utils/reactflowUtils.ts
Diagram: Handle Type Structure
Sources: src/frontend/src/types/flow/index.ts97-115 src/frontend/src/types/api/index.ts81-128
isValidConnectionisValidConnection in src/frontend/src/utils/reactflowUtils.ts325-438 is the primary gate that runs when a user drags a wire between two ports. ReactFlow calls it synchronously before committing an edge. If it returns false, the connection is silently dropped.
if (source === target) return false;
Prevents a node from connecting to itself.
The function parses the JSON-encoded handle strings back into sourceHandleType and targetHandleType objects, then checks compatibility using this precedence:
Diagram: Type Compatibility Decision Tree
Sources: src/frontend/src/utils/reactflowUtils.ts325-438
For non-loop, non-list inputs, the function checks whether any existing edge already targets the same targetHandle string:
edgesArray.find((e) => e.targetHandle === targetHandle)
If a match is found, the connection is rejected. Fields with list: true in their template definition accept multiple incoming edges.
A targetHandleType whose output_types field is non-null signals a loop input — an output port that also accepts incoming edges to form a cycle. Detection:
When connecting to a loop input, the compatibility check becomes:
findCyclePath performs a DFS from the target node through outgoing edges to see if it can reach the source node. If a cycle is found, the function checks whether any edge in that cycle path is a loop-input edge:
Cycles are permitted only when a loop-input node is present in the path. Plain directed cycles without a loop node are rejected.
Sources: src/frontend/src/utils/reactflowUtils.ts341-437
cleanEdgescleanEdges in src/frontend/src/utils/reactflowUtils.ts83-255 audits every existing edge whenever nodes change. It removes edges that are no longer structurally valid and returns a list of broken edge descriptors for user display.
cleanEdges is called in the Zustand flow store in three places:
| Store action | Call site |
|---|---|
resetFlow | src/frontend/src/stores/flowStore.ts224 |
setNodes | src/frontend/src/stores/flowStore.ts309 |
setNode | src/frontend/src/stores/flowStore.ts364 |
This means every time nodes are updated — e.g., after dragging a component, updating component code, or loading a flow — edges are automatically re-validated.
Diagram: cleanEdges Validation Stages
Sources: src/frontend/src/utils/reactflowUtils.ts83-255
Edges targeting fields that have advanced: true are also cleaned. clearHandlesFromAdvancedFields in src/frontend/src/utils/reactflowUtils.ts257-289 removes any connected edges to advanced fields when a component's template is updated (e.g., after editing code in CodeAreaModal).
filterHiddenFieldsEdges at src/frontend/src/utils/reactflowUtils.ts296-314 removes edges targeting fields with show: false in the node template:
cleanEdges returns { edges, brokenEdges }. The brokenEdges array contains human-readable descriptors with source display name, output display name, and target field display name. resetFlow in the flow store uses this to call useAlertStore.setErrorData with a warning titled BROKEN_EDGES_WARNING.
Sources: src/frontend/src/stores/flowStore.ts224-258 src/frontend/src/utils/reactflowUtils.ts83-121
validateNode and validateEdgeThese functions perform semantic validation — checking that components are fully configured — separately from the structural/type validation above.
validateNodeDefined at src/frontend/src/utils/reactflowUtils.ts606-665 Iterates the node's template and flags errors for each field where:
required === trueshow === truevalue is undefined, null, or ""edge.targetHandle.fieldName === t && edge.targetHandle.id === node.id)Also validates dict type fields for duplicate keys and empty key values.
validateNodesDefined at src/frontend/src/utils/reactflowUtils.ts667-689 Maps validateNode over all nodes in the flow and returns only nodes with errors. Used to gate flow execution.
validateEdgeDefined at src/frontend/src/utils/reactflowUtils.ts691-703 For edges connected to a loop input (targetHandleObject.output_types is non-null), it checks that the edge is part of a complete cycle using the hasLoop helper. Returns [INCOMPLETE_LOOP_ERROR_ALERT] if the loop input edge has no return path.
Sources: src/frontend/src/utils/reactflowUtils.ts606-760
Diagram: Validation Integration Points
Sources: src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx385-392 src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx561-579 src/frontend/src/stores/flowStore.ts306-381
isValidConnection as a ReactFlow PropThe ReactFlow component in PageComponent receives isValidConnection directly as a prop. ReactFlow calls it while the user is dragging a connection wire, before onConnect fires. If isValidConnection returns false, no onConnect event is emitted and no edge is created.
When a user drags an existing edge endpoint to a new port, ReactFlow fires onEdgeUpdate. The handler at src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx561-573 re-validates the new connection before calling reconnectEdge:
If isValidConnection returns false, the edgeUpdateSuccessful ref stays false and onEdgeUpdateEnd removes the edge entirely.
Sources: src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx557-580
When a target field has type === "model" (a ModelInput), cleanEdges applies a default inputTypes derived from the field's model_type property:
This allows ModelInput fields to accept connections without explicitly listing input_types in the Python definition.
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.