n8n-io/n8n · error · Error
LLM does not support bindTools - cannot use tools for node…
Error message
LLM does not support bindTools - cannot use tools for node discovery
What it means
A capability guard in bindToolsToLlm: the LLM instance injected into the chat setup handler has no bindTools method, so LangChain-style tool binding for node discovery is impossible with this model adapter. The error is thrown before any tool call is attempted — it fires at wiring time and indicates an incompatible or mock LLM was configured.
Solutions
- Configure an LLM that implements LangChain's bindTools (e.g. ChatOpenAI, ChatAnthropic) instead of the current adapter
- Wrap the raw model in a LangChain chat-model adapter that supports tool calling
- If running tests, provide a mock LLM whose bindTools returns a tool-capable model
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at packages/@n8n/ai-workflow-builder.ee/src/code-builder/handlers/chat-setup-handler.ts:219 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/243404266a364643.
Report an issue: GitHub.
Appendix: source
Thrown at packages/@n8n/ai-workflow-builder.ee/src/code-builder/handlers/chat-setup-handler.ts:219
return generateWorkflowCode({
workflow: currentWorkflow,
executionSchema: payload.workflowContext?.executionSchema,
executionData: payload.workflowContext?.executionData,
expressionValues: payload.workflowContext?.expressionValues,
valuesExcluded: payload.workflowContext?.valuesExcluded,
pinnedNodes: payload.workflowContext?.pinnedNodes,
});
}
/**
* Bind tools to LLM
*
* @returns LLM with tools bound, typed for use with AgentIterationHandler
*/
private bindToolsToLlm(textEditorEnabled: boolean, hasPlanOutput: boolean): LlmWithTools {
if (!this.llm.bindTools) {
throw new Error('LLM does not support bindTools - cannot use tools for node discovery');
}
// When an approved plan is provided, exclude get_suggested_nodes
// because the plan already contains curated node suggestions per step
let tools: Array<
| StructuredToolInterface
| typeof TEXT_EDITOR_TOOL
| typeof VALIDATE_TOOL
| typeof BATCH_STR_REPLACE_TOOL
> = hasPlanOutput ? this.tools.filter((t) => t.name !== 'get_suggested_nodes') : this.tools;
if (textEditorEnabled) {
tools = [...tools, TEXT_EDITOR_TOOL, VALIDATE_TOOL, BATCH_STR_REPLACE_TOOL];
}
return this.llm.bindTools(tools) as LlmWithTools;
}
View on GitHub (pinned to 5ac6606e81)