From bc99f41a516555c0cda98df5c3dff496dc5f5f66 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 14 Nov 2025 23:04:02 -0500 Subject: [PATCH] fix: prevent duplicate tool_result blocks in native tool protocol (#9248) --- .../assistant-message/presentAssistantMessage.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts index b692401184..4d3fba3104 100644 --- a/src/core/assistant-message/presentAssistantMessage.ts +++ b/src/core/assistant-message/presentAssistantMessage.ts @@ -277,6 +277,9 @@ export async function presentAssistantMessage(cline: Task) { break } + // Track if we've already pushed a tool result for this tool call (native protocol only) + let hasToolResult = false + const pushToolResult = (content: ToolResponse) => { // Check if we're using native tool protocol const isNative = isNativeProtocol(getToolProtocolFromSettings()) @@ -285,6 +288,14 @@ export async function presentAssistantMessage(cline: Task) { const toolCallId = (block as any).id if (isNative && toolCallId) { + // For native protocol, only allow ONE tool_result per tool call + if (hasToolResult) { + console.warn( + `[presentAssistantMessage] Skipping duplicate tool_result for tool_use_id: ${toolCallId}`, + ) + return + } + // For native protocol, add as tool_result block let resultContent: string if (typeof content === "string") { @@ -309,6 +320,8 @@ export async function presentAssistantMessage(cline: Task) { tool_use_id: toolCallId, content: resultContent, } as Anthropic.ToolResultBlockParam) + + hasToolResult = true } else { // For XML protocol, add as text blocks (legacy behavior) cline.userMessageContent.push({ type: "text", text: `${toolDescription()} Result:` })