FlowiseAI/Flowise · error · Error
${getErrorMessage(e)}
Error message
${getErrorMessage(e)} What it means
Inside Agent.handleToolCalls, each tool invocation is wrapped in try/catch. On failure the error is logged, recorded into usedTools with the error message, streamed via sseStreamer, and re-thrown verbatim through getErrorMessage(e). This propagates the original tool failure (not wrapped) up to Agent.run's catch, which wraps it as 'Error in Agent node'.
Source
Thrown at packages/components/nodes/agentflow/Agent/Agent.ts:2361
const errMsg = getErrorMessage(e)
let toolInput = toolCall.args
if (typeof errMsg === 'string' && errMsg.includes(TOOL_ARGS_PREFIX)) {
const [_, args] = errMsg.split(TOOL_ARGS_PREFIX)
try {
toolInput = JSON.parse(args)
} catch (e) {
console.error('Error parsing tool input from tool:', e)
}
}
usedTools.push({
tool: selectedTool.name,
toolInput,
toolOutput: '',
error: getErrorMessage(e)
})
sseStreamer?.streamUsedToolsEvent(chatId, flatten(usedTools))
throw new Error(getErrorMessage(e))
}
}
}
// Return direct tool output if there's exactly one tool with returnDirect
if (response.tool_calls.length === 1) {
const selectedTool = toolsInstance.find((tool) => tool.name === response.tool_calls?.[0]?.name)
if (selectedTool && selectedTool.returnDirect) {
const lastToolOutput = usedTools[0]?.toolOutput || ''
const lastToolOutputString = typeof lastToolOutput === 'string' ? lastToolOutput : JSON.stringify(lastToolOutput, null, 2)
if (sseStreamer && !isStructuredOutput) {
sseStreamer.streamTokenEvent(chatId, lastToolOutputString)
}
return {
response: new AIMessageChunk(lastToolOutputString),
usedTools,View on GitHub (pinned to abe4a8601a)
Solutions
- Identify which tool failed from the streamed usedTools event (selectedTool.name) and its error field.
- Open that tool node and test it in isolation; fix its config/credential/endpoint.
- If the tool is external, verify connectivity and auth from the Flowise host.
- Re-run the agent once the failing tool is corrected; consider marking the tool optional if appropriate.
Defensive patterns
Strategy: try-catch
Validate before calling
async function safeToolInvoke(tool, input) {
try { return { ok: true, value: await tool.invoke(input) } }
catch (e) { return { ok: false, error: e } }
}
// pre-flight: validate tool is init'd and credentialed
for (const t of toolsInstance) {
if (typeof t.invoke !== 'function') throw new Error(`Tool ${t.name} is not invokable`)
} Type guard
function isInvokableTool(t) { return !!t && typeof t.invoke === 'function' } Try / catch
try { /* agent.run */ }
catch (e) {
const m = e instanceof Error ? e.message : String(e)
// the streamed usedTools event carries the failing tool name + error;
// match on tool name to route to the right remediation
if (/401|Unauthorized/.test(m)) { /* refresh tool credential */ }
throw e
} Prevention
- Configure credentials on every tool sub-node and test them in isolation.
- Make tool endpoints resilient and retryable.
- Monitor usedTools events for non-empty error fields.
When it happens
Trigger: A configured tool node throwing during .invoke/.call: HTTP tool hitting a bad endpoint, calculator tool bad input, RAG/tool credential missing, custom tool code throwing, MCP tool transport error, tool input args failing JSON parse inside the tool.
Common situations: Tool sub-node missing its credential; tool API endpoint down or returning non-200; tool input schema mismatch; version skew between tool schema and tool implementation; network/firewall blocking the tool's outbound call.
Related errors
- Agent needs to have a function calling capable models.
- Error executing tool. Tool: ${tool.name}. Thread ID: ${threa
- Tool ${call.name} not found.
- Model is required
- Invalid human input type. Expected 'proceed' or 'reject', bu
AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12).
Data as JSON: /api/errors/430ca3a92957dabf.
Report an issue: GitHub.