{"record":{"id":"b47c321be4a2fe81","repo":"FlowiseAI/Flowise","slug":"toolnode-only-accepts-aimessages-as-input","errorCode":null,"errorMessage":"ToolNode only accepts AIMessages as input.","messagePattern":"ToolNode only accepts AIMessages as input\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/sequentialagents/Agent/Agent.ts","lineNumber":1007,"sourceCode":"\n        // Check if input is an array of BaseMessage[]\n        if (Array.isArray(input)) {\n            messages = input\n        }\n        // Check if input is IStateWithMessages\n        else if ((input as IStateWithMessages).messages) {\n            messages = (input as IStateWithMessages).messages\n        }\n        // Handle MessagesState type\n        else {\n            messages = (input as MessagesState).messages\n        }\n\n        // Get the last message\n        const message = messages[messages.length - 1]\n\n        if (message._getType() !== 'ai') {\n            throw new Error('ToolNode only accepts AIMessages as input.')\n        }\n\n        // Extract all properties except messages for IStateWithMessages\n        const { messages: _, ...inputWithoutMessages } = Array.isArray(input) ? { messages: input } : input\n        const ChannelsWithoutMessages = {\n            chatId: this.options.chatId,\n            sessionId: this.options.sessionId,\n            input: this.inputQuery,\n            state: inputWithoutMessages\n        }\n\n        const outputs = await Promise.all(\n            (message as AIMessage).tool_calls?.map(async (call) => {\n                const tool = this.tools.find((tool) => tool.name === call.name)\n                if (tool === undefined) {\n                    throw new Error(`Tool ${call.name} not found.`)\n                }\n                if (tool && (tool as any).setFlowObject) {","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/sequentialagents/Agent/Agent.ts#L989-L1025","documentation":"ToolNode.run extracts the last message from input and checks `message._getType() !== 'ai'`. Tool nodes are only meaningful immediately after an AIMessage that carries `tool_calls` — they execute those calls and produce ToolMessages. Receiving a Human/System/Tool message means the graph is wired wrong.","triggerScenarios":"ToolNode receives a state (or BaseMessage[]) whose last message is not an AIMessage — e.g. after a HumanMessage, a SystemMessage, or another ToolMessage.","commonSituations":"Graph routes a HumanMessage straight into a ToolNode without an intervening LLM/agent step; ToolNode is chained after another ToolNode; conversation history's last entry is a tool result that wasn't followed by an AI turn; state was initialized with only a human message.","solutions":["Ensure the ToolNode is preceded by an Agent/LLM node whose output is an AIMessage with `tool_calls`.","Check `state.messages[state.messages.length - 1]._getType()` before invoking the tool branch.","Restructure the graph so the ToolNode always sits downstream of an LLM call."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"function lastMessageIsAI(input) {\n  const messages = Array.isArray(input) ? input : input?.messages ?? []\n  const last = messages[messages.length - 1]\n  return last?._getType?.() === 'ai'\n}\n\nif (!lastMessageIsAI(state)) {\n  throw new Error('ToolNode expects the last message to be an AIMessage with tool_calls.')\n}","typeGuard":"function isAIMessage(m): m is AIMessage {\n  return m != null && typeof m._getType === 'function' && m._getType() === 'ai'\n}","tryCatchPattern":null,"preventionTips":["Always place ToolNode downstream of an Agent/LLM node that produces AIMessages with tool_calls.","Never chain ToolNode directly after a HumanMessage or another ToolMessage.","Inspect `state.messages.at(-1)._getType()` when debugging graph routing."],"tags":["tool-node","graph-wiring","messages","runtime"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}