FlowiseAI/Flowise · error · Error

Tool not found.

Error message

Tool ${call.name} not found.

What it means

For each `tool_call` on the incoming AIMessage, ToolNode looks up `this.tools.find(t => t.name === call.name)`. If the model called a tool name that is not registered in the ToolNode's `tools` array, lookup returns undefined and the node throws. The error names the missing tool so you can see what the model asked for.

Solutions

  1. Attach the missing tool to the Agent node so it is registered in the ToolNode's tools array.
  2. Use stable, immutable tool `name` values — avoid renaming tools after deployment.
  3. Start a new chat session after changing the toolset so stale tool_calls do not replay.
  4. Verify `tool.name` matches what the model is instructed to call.
Defensive patterns

Strategy: validation

Validate before calling

function assertAllToolCallsResolvable(toolCalls, tools) {
  const names = new Set(tools.map((t) => t.name))
  for (const call of toolCalls ?? []) {
    if (!names.has(call.name)) {
      throw new Error(`Tool '${call.name}' is not attached. Available: ${[...names].join(', ')}`)
    }
  }
}

assertAllToolCallsResolvable(aiMessage.tool_calls, nodeTools)

Type guard

function toolIsRegistered(name: string, tools: { name: string }[]): boolean {
  return tools.some((t) => t.name === name)
}

Try / catch

try {
  await toolNode.invoke(input, config)
} catch (e) {
  if (e?.message?.startsWith('Tool ') && e.message.endsWith(' not found.')) {
    // model hallucinated or toolset changed — re-ask the agent without the stale call
    return [{ content: `Tool not available: ${e.message}`, tool_call_id: call.id }]
  }
  throw e
}

Prevention

When it happens

Trigger: The AIMessage contains a `tool_call` whose `name` does not match any tool passed into the ToolNode constructor — typically because the tool was never attached to the Agent, was renamed, or the model hallucinated a name.

Common situations: Tools were added/removed on the Agent after a conversation started (the cached AIMessage references an old name); the model hallucinated a tool name; tool display name differs from internal `name`; a tool was renamed between flow versions and an old session replays.

Related errors


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

Appendix: source

Thrown at packages/components/nodes/sequentialagents/Agent/Agent.ts:1023

        if (message._getType() !== 'ai') {
            throw new Error('ToolNode only accepts AIMessages as input.')
        }

        // Extract all properties except messages for IStateWithMessages
        const { messages: _, ...inputWithoutMessages } = Array.isArray(input) ? { messages: input } : input
        const ChannelsWithoutMessages = {
            chatId: this.options.chatId,
            sessionId: this.options.sessionId,
            input: this.inputQuery,
            state: inputWithoutMessages
        }

        const outputs = await Promise.all(
            (message as AIMessage).tool_calls?.map(async (call) => {
                const tool = this.tools.find((tool) => tool.name === call.name)
                if (tool === undefined) {
                    throw new Error(`Tool ${call.name} not found.`)
                }
                if (tool && (tool as any).setFlowObject) {
                    // @ts-ignore
                    tool.setFlowObject(ChannelsWithoutMessages)
                }
                let output = await tool.invoke(call.args, config)
                let sourceDocuments: Document[] = []
                let artifacts = []

                if (output?.includes(SOURCE_DOCUMENTS_PREFIX)) {
                    const outputArray = output.split(SOURCE_DOCUMENTS_PREFIX)
                    output = outputArray[0]
                    const docs = outputArray[1]
                    try {
                        sourceDocuments = JSON.parse(docs)
                    } catch (e) {
                        console.error('Error parsing source documents from tool')
                    }

View on GitHub (pinned to abe4a8601a)