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

  1. Configure an LLM that implements LangChain's bindTools (e.g. ChatOpenAI, ChatAnthropic) instead of the current adapter
  2. Wrap the raw model in a LangChain chat-model adapter that supports tool calling
  3. 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)