-
Notifications
You must be signed in to change notification settings - Fork 3k
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Checked other resources
- This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
- I added a very descriptive title to this issue.
- I searched the LangChain.js documentation with the integrated search.
- I used the GitHub search to find a similar question and didn't find it.
- I am sure that this is a bug in LangChain.js rather than my code.
- The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
Example Code
import { createAgent, FakeToolCallingModel } from 'langchain'
import { z } from 'zod'
import { tool } from '@langchain/core/tools'
async function main() {
// Define a simple tool
const getWeather = tool(({ location }) => `Weather in ${location}: sunny`, {
name: 'get_weather',
description: 'Get weather for a location',
schema: z.object({
location: z.string()
})
})
// Create a fake model that returns an invalid tool call
const fakeModel = new FakeToolCallingModel({
toolCalls: [
// First call: returns invalid tool name
[
{
name: 'nonexistent_tool', // This tool doesn't exist!
args: { foo: 'bar' },
id: 'call_123'
}
],
// Second call: empty (final response)
[]
]
})
const agent = createAgent({
model: fakeModel,
tools: [getWeather]
})
console.log('Testing createAgent with invalid tool call...')
console.log('Expected: Agent should handle error gracefully')
console.log('Actual:\n')
try {
const result = await agent.invoke({
messages: [{ role: 'user', content: "What's the weather?" }]
})
console.log('✅ Agent completed')
console.log('Last message:', result.messages[result.messages.length - 1].content)
} catch (error: any) {
console.error('❌ UNHANDLED ERROR:', error.message)
console.error('\nStack:', error.stack)
}
}
main()Error Message and Stack Trace (if applicable)
Testing createAgent with invalid tool call...
Expected: Agent should handle error gracefully
Actual:
❌ UNHANDLED ERROR: Tool "nonexistent_tool" not found.
Stack: Error: Tool "nonexistent_tool" not found.
at ToolNode.runTool (/.pnpm/langchain@1.2.7_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter_e96464e95e75121a98af3e7edea629c2/node_modules/langchain/src/agents/nodes/ToolNode.ts:350:13)
at ToolNode.run (/.pnpm/langchain@1.2.7_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter_e96464e95e75121a98af3e7edea629c2/node_modules/langchain/src/agents/nodes/ToolNode.ts:395:29)
at ToolNode.func (/.pnpm/langchain@1.2.7_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter_e96464e95e75121a98af3e7edea629c2/node_modules/langchain/src/agents/nodes/ToolNode.ts:194:14)
at <anonymous> (/.pnpm/langchain@1.2.7_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter_e96464e95e75121a98af3e7edea629c2/node_modules/langchain/src/agents/RunnableCallable.ts:73:24)
at AsyncLocalStorage.run (node:internal/async_local_storage/async_context_frame:63:14)
at AsyncLocalStorageProvider.runWithConfig (/.pnpm/@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp-prot_9973472e3d75ca47e707f3f4889b068e/node_modules/@langchain/core/src/singletons/async_local_storage/index.ts:88:20)
at ToolNode.invoke (/.pnpm/langchain@1.2.7_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter_e96464e95e75121a98af3e7edea629c2/node_modules/langchain/src/agents/RunnableCallable.ts:71:66)
at RunnableSequence.invoke (/.pnpm/@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp-prot_9973472e3d75ca47e707f3f4889b068e/node_modules/@langchain/core/src/runnables/base.ts:1899:30)
at async _runWithRetry (/.pnpm/@langchain+langgraph@1.0.15_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@openteleme_874695521d2034e85775d62b8ebe59d3/node_modules/@langchain/langgraph/src/pregel/retry.ts:103:16)
at async PregelRunner._executeTasksWithRetry (/.pnpm/@langchain+langgraph@1.0.15_@langchain+core@1.1.12_@opentelemetry+api@1.9.0_@openteleme_874695521d2034e85775d62b8ebe59d3/node_modules/@langchain/langgraph/src/pregel/runner.ts:330:27)
Description
When ToolNode receives a tool call with a name that doesn't match any registered tool (e.g., when an LLM hallucinates a tool name) it throws an unhandled error instead of returning a ToolMessage with status: "error".
This happens because there are two "tool not found" checks in runTool():
- Inside baseHandler (line ~290-292) - this IS wrapped by try-catch
- Outside any try-catch (line ~348-351) - this throws BEFORE error handling
// This check runs BEFORE the try-catch blocks
const tool = this.tools.find((t) => t.name === call.name);
if (!tool) {
throw new Error(`Tool "${call.name}" not found.`); // Unhandled!
}The error at line ~350 is thrown before reaching either:
- The wrapToolCall middleware try-catch (line ~361-371)
- The direct baseHandler try-catch (line ~377-385)
Expected behavior
When handleToolErrors is true (default), invalid tool names should be caught and returned as a ToolMessage with the error, allowing the LLM to see its mistake and retry. This is how it works in @langchain/langgraph's ToolNode.
Current behavior
The error propagates up and crashes the agent.
System Info
langchain@1.2.11
MacOS
Node 24.12.0
pnpm 10.25
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working