From 95af975a37dc3c483e21773f7896d742cbbe97f5 Mon Sep 17 00:00:00 2001 From: Benjamin Schroth <68321970+schrothbn@users.noreply.github.com> Date: Mon, 15 Dec 2025 15:12:44 +0100 Subject: [PATCH] fix(AI Agent Node): Handle continueOnFail for maxIterations correctly (#23218) --- .../nodes/agents/Agent/agents/ToolsAgent/V3/execute.ts | 7 ++----- .../Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/execute.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/execute.ts index 14d3769ed92..8b2220765b0 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/execute.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/execute.ts @@ -7,7 +7,7 @@ import type { EngineResponse, } from 'n8n-workflow'; -import { buildExecutionContext, executeBatch, checkMaxIterations } from './helpers'; +import { buildExecutionContext, executeBatch } from './helpers'; import type { RequestResponseMetadata } from './types'; /* ----------------------------------------------------------- @@ -31,12 +31,9 @@ export async function toolsAgentExecute( ): Promise> { this.logger.debug('Executing Tools Agent V3'); - // Check max iterations if this is a continuation of a previous execution - const maxIterations = this.getNodeParameter('options.maxIterations', 0, 10) as number; - checkMaxIterations(response, maxIterations, this.getNode()); + let request: EngineRequest | undefined = undefined; const returnData: INodeExecutionData[] = []; - let request: EngineRequest | undefined = undefined; // Build execution context with shared configuration const executionContext = await buildExecutionContext(this); diff --git a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts index 200f84480c7..68c7cbd206f 100644 --- a/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts +++ b/packages/@n8n/nodes-langchain/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.ts @@ -1,7 +1,7 @@ import type { BaseChatModel } from '@langchain/core/language_models/chat_models'; import type { AgentRunnableSequence } from '@langchain/classic/agents'; import type { BaseChatMemory } from '@langchain/classic/memory'; -import { NodeOperationError } from 'n8n-workflow'; +import { assertParamIsNumber, NodeOperationError } from 'n8n-workflow'; import type { IExecuteFunctions, ISupplyDataFunctions, @@ -17,6 +17,7 @@ import { createAgentSequence } from './createAgentSequence'; import { finalizeResult } from './finalizeResult'; import { prepareItemContext } from './prepareItemContext'; import { runAgent } from './runAgent'; +import { checkMaxIterations } from './checkMaxIterations'; type BatchResult = AgentResult | EngineRequest; /** @@ -47,9 +48,15 @@ export async function executeBatch( const returnData: INodeExecutionData[] = []; let request: EngineRequest | undefined = undefined; + // Check max iterations if this is a continuation of a previous execution + const maxIterations = ctx.getNodeParameter('options.maxIterations', 0, 10); + assertParamIsNumber('options.maxIterations', maxIterations, ctx.getNode()); + const batchPromises = batch.map(async (_item, batchItemIndex) => { const itemIndex = startIndex + batchItemIndex; + checkMaxIterations(response, maxIterations, ctx.getNode()); + const itemContext = await prepareItemContext(ctx, itemIndex, response); const { tools, prompt, options, outputParser } = itemContext;