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
- In the Flowise canvas, draw a connection from an upstream sequential node's output into this Custom Function's 'Sequential Node' input.
- Save the chatflow again so the edge is serialized into inputs.sequentialNode.
- 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
- Run a graph-wiring lint pass before save: every non-Start sequential node must have >=1 incoming edge.
- After cloning a flow, re-verify all Sequential Node params are populated.
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
- End must have a predecessor!
- Execute Flow must have a predecessor!
- Agent must have a predecessor!
- Agent must have a predecessor!
- Condition must have a predecessor!
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/547c89bd83b208bf.
Report an issue: GitHub.