Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Heuristic:FlowiseAI Flowise Edge Connection Type Matching

From Leeroopedia
Knowledge Sources
Domains Validation, Flow_Editor
Last Updated 2026-02-12 07:30 GMT

Overview

Type-safe edge connection validation ensuring only compatible node types can be connected in the Flowise canvas editor.

Description

Flowise uses a handle-based type system for validating edge connections between nodes. Each node output handle encodes its type in the handle ID format: `{nodeId}-output-{outputName}-{Type1|Type2}`. Similarly, input handles follow: `{nodeId}-input-{inputName}-{Type1|Type2}`. When a user drags an edge between nodes, the system extracts the type suffix from both handles and checks for intersection. For chatflows, it also enforces single vs. list connection constraints (an input marked as `list` accepts multiple edges; otherwise only one). For agentflow v2, an additional DFS-based cycle detection prevents creating DAG violations.

Usage

Apply this heuristic when building custom nodes for Flowise, debugging connection errors in the canvas, or understanding why certain node types cannot connect. The type matching system determines which integrations are compatible without trial and error.

The Insight (Rule of Thumb)

  • Action: When defining custom node outputs, encode the compatible types in the handle ID using the pipe (`|`) separator for multiple types
  • Value: Format: `{nodeId}-output-{name}-{BaseType1|BaseType2}` — the last segment after the final dash contains the type(s)
  • Trade-off: Overly permissive types (e.g., accepting `BaseChain`) allow connections that may fail at runtime; overly restrictive types reduce composability
  • Key Rules:
    • Types are extracted from the last dash-separated segment of the handle ID
    • Multiple types are separated by the pipe character (`|`)
    • A type match occurs when any source type matches any target type
    • Non-list inputs accept only one incoming edge; list inputs accept multiple
    • AgentFlow v2 additionally rejects self-connections and cycle-creating edges

Reasoning

The type system prevents incompatible connections at design time rather than at runtime. For example, connecting a `ChatOpenAI` (type: `BaseChatModel`) to an input expecting `BaseRetriever` would fail at execution. The handle-based approach embeds type information directly in the ReactFlow handle ID, avoiding the need for a separate type registry lookup. The list vs. single constraint ensures that inputs expecting a single model do not accidentally receive multiple conflicting models.

The agentflow v2 cycle detection uses DFS graph traversal: before adding edge `source -> target`, it checks if a path exists from `target` back to `source` in the existing graph. If such a path exists, adding the edge would create a cycle, which is invalid for a DAG-based execution flow.

Code Evidence

Type extraction and matching from `packages/ui/src/utils/genericHelper.js:414-449`:

export const isValidConnection = (connection, reactFlowInstance) => {
    const sourceHandle = connection.sourceHandle
    const targetHandle = connection.targetHandle
    const target = connection.target

    //sourceHandle: "llmChain_0-output-llmChain-BaseChain"
    //targetHandle: "mrlkAgentLLM_0-input-model-BaseLanguageModel"

    let sourceTypes = sourceHandle.split('-')[sourceHandle.split('-').length - 1].split('|')
    sourceTypes = sourceTypes.map((s) => s.trim())
    let targetTypes = targetHandle.split('-')[targetHandle.split('-').length - 1].split('|')
    targetTypes = targetTypes.map((t) => t.trim())

    if (targetTypes.some((t) => sourceTypes.includes(t))) {
        // Check single vs list constraint
        if ((targetNodeInputAnchor && !targetNodeInputAnchor?.list &&
             !reactFlowInstance.getEdges().find((e) => e.targetHandle === targetHandle)) ||
            targetNodeInputAnchor?.list) {
            return true
        }
    }
    return false
}

Cycle detection for AgentFlow v2 from `packages/ui/src/utils/genericHelper.js:451-506`:

export const isValidConnectionAgentflowV2 = (connection, reactFlowInstance) => {
    const source = connection.source
    const target = connection.target

    // Prevent self connections
    if (source === target) { return false }

    // Check if this connection would create a cycle in the graph
    if (wouldCreateCycle(source, target, reactFlowInstance)) { return false }

    return true
}

const wouldCreateCycle = (sourceId, targetId, reactFlowInstance) => {
    // Build directed graph from existing edges
    const graph = {}
    const edges = reactFlowInstance.getEdges()
    edges.forEach((edge) => {
        if (!graph[edge.source]) graph[edge.source] = []
        graph[edge.source].push(edge.target)
    })

    // DFS: Check if there's a path from target to source
    function hasPath(current, destination) {
        if (current === destination) return true
        if (visited.has(current)) return false
        visited.add(current)
        for (const neighbor of (graph[current] || [])) {
            if (hasPath(neighbor, destination)) return true
        }
        return false
    }
    return hasPath(targetId, sourceId)
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment