FlowiseAI/Flowise · error · Error

Custom function must have a predecessor!

Error message

Custom function must have a predecessor!

What it means

Thrown at init() of the Custom Function sequential node when nodeData.inputs.sequentialNode is undefined or an empty array. The sequential-agent graph (LangGraph) requires every non-Start node to declare at least one predecessor so the edges can be wired; a Custom Function with no incoming sequential connection cannot be placed in the graph.

Source

Thrown at packages/components/nodes/sequentialagents/CustomFunction/CustomFunction.ts:101

                        name: 'stateObj',
                        description: "Return as state object, ex: { foo: bar }. This will update the custom state 'foo' to 'bar'"
                    }
                ],
                default: 'aiMessage'
            }
        ]
    }

    async init(nodeData: INodeData, input: string, options: ICommonObject): Promise<any> {
        const functionName = nodeData.inputs?.functionName as string
        const javascriptFunction = nodeData.inputs?.javascriptFunction as string
        const functionInputVariablesRaw = nodeData.inputs?.functionInputVariables
        const appDataSource = options.appDataSource as DataSource
        const databaseEntities = options.databaseEntities as IDatabaseEntity
        const sequentialNodes = nodeData.inputs?.sequentialNode as ISeqAgentNode[]
        const returnValueAs = nodeData.inputs?.returnValueAs as string

        if (!sequentialNodes || !sequentialNodes.length) throw new Error('Custom function must have a predecessor!')

        const executeFunc = async (state: ISeqAgentsState) => {
            const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
            const flow = {
                chatflowId: options.chatflowid,
                sessionId: options.sessionId,
                chatId: options.chatId,
                input,
                state
            }

            let inputVars: ICommonObject = {}
            if (functionInputVariablesRaw) {
                try {
                    inputVars =
                        typeof functionInputVariablesRaw === 'object' ? functionInputVariablesRaw : JSON.parse(functionInputVariablesRaw)
                } catch (exception) {
                    throw new Error('Invalid JSON in the Custom Function Input Variables: ' + exception)

View on GitHub (pinned to abe4a8601a)

Solutions

  1. In the Flowise canvas, draw a connection from an upstream sequential node's output into this Custom Function's 'Sequential Node' input.
  2. Save the chatflow again so the edge is serialized into inputs.sequentialNode.
  3. Reopen the node and confirm a predecessor appears in the 'Sequential Node' parameter.
Defensive patterns

Strategy: validation

Validate before calling

const seq = nodeData.inputs?.sequentialNode
if (!Array.isArray(seq) || seq.length === 0) {
  throw new Error('Custom Function must have a predecessor! Connect an upstream sequential node before init.')
}

Type guard

const hasPredecessor = (n: INodeData): boolean =>
  Array.isArray(n.inputs?.sequentialNode) && (n.inputs!.sequentialNode as any[]).length > 0

Prevention

When it happens

Trigger: The Custom Function node was dropped on the canvas but never linked from an Agent / Condition / LLMNode / ToolNode / CustomFunction / ExecuteFlow output; the visual edge exists but was not serialized into inputs.sequentialNode (stale saved chatflow); sequentialNode was set to an empty array by a corrupted import.

Common situations: Building a new sequential flow and forgetting the wire before save/preview; copying a node without copying its edges; loading an older chatflow whose schema predates the sequentialNode field.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/547c89bd83b208bf. Report an issue: GitHub.