From 803287516d39484b6d47515ab85594583ce37219 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Tue, 27 Jan 2026 18:04:14 +0000 Subject: [PATCH] fix: improve error messages for API providers without native tool calling support When an API provider (such as OpenAI-compatible proxies like kie.ai) does not properly support native function/tool calling, the model may output XML-formatted tool calls in its text response. The previous error messages were technical and confusing for users. Updated error messages to: - Explain what happened in user-friendly terms - Identify the likely cause (API provider not supporting native tool calling) - Provide actionable guidance Fixes #11011 --- .../presentAssistantMessage-images.spec.ts | 16 ++++++++++------ .../presentAssistantMessage-unknown-tool.spec.ts | 8 +++++--- .../assistant-message/presentAssistantMessage.ts | 8 ++++++-- src/core/tools/BaseTool.ts | 3 ++- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts b/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts index 9adac74fd2f..60d07596369 100644 --- a/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts +++ b/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts @@ -182,9 +182,11 @@ describe("presentAssistantMessage - Image Handling in Native Tool Calling", () = const textBlocks = mockTask.userMessageContent.filter((item: any) => item.type === "text") expect(textBlocks.length).toBeGreaterThan(0) - expect(textBlocks.some((b: any) => String(b.text).includes("XML tool calls are no longer supported"))).toBe( - true, - ) + expect( + textBlocks.some((b: any) => + String(b.text).includes("does not fully support OpenAI's function/tool calling"), + ), + ).toBe(true) // Should not proceed to execute tool or add images as tool output. expect(mockTask.userMessageContent.some((item: any) => item.type === "image")).toBe(false) }) @@ -331,9 +333,11 @@ describe("presentAssistantMessage - Image Handling in Native Tool Calling", () = await presentAssistantMessage(mockTask) const textBlocks = mockTask.userMessageContent.filter((item: any) => item.type === "text") - expect(textBlocks.some((b: any) => String(b.text).includes("XML tool calls are no longer supported"))).toBe( - true, - ) + expect( + textBlocks.some((b: any) => + String(b.text).includes("does not fully support OpenAI's function/tool calling"), + ), + ).toBe(true) // Ensure no tool_result blocks were added expect(mockTask.userMessageContent.some((item: any) => item.type === "tool_result")).toBe(false) }) diff --git a/src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts b/src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts index ed90127b5b8..e736f4b99c0 100644 --- a/src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts +++ b/src/core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts @@ -131,9 +131,11 @@ describe("presentAssistantMessage - Unknown Tool Handling", () => { // Should not execute tool; should surface a clear error message. const textBlocks = mockTask.userMessageContent.filter((item: any) => item.type === "text") expect(textBlocks.length).toBeGreaterThan(0) - expect(textBlocks.some((b: any) => String(b.text).includes("XML tool calls are no longer supported"))).toBe( - true, - ) + expect( + textBlocks.some((b: any) => + String(b.text).includes("does not fully support OpenAI's function/tool calling"), + ), + ).toBe(true) // Verify consecutiveMistakeCount was incremented expect(mockTask.consecutiveMistakeCount).toBe(1) diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts index b0b330d9907..228ea07f3b1 100644 --- a/src/core/assistant-message/presentAssistantMessage.ts +++ b/src/core/assistant-message/presentAssistantMessage.ts @@ -317,7 +317,9 @@ export async function presentAssistantMessage(cline: Task) { // fail fast with a clear error. if (containsXmlToolMarkup(content)) { const errorMessage = - "XML tool calls are no longer supported. Remove any XML tool markup (e.g. ...) and use native tool calling instead." + "The model is outputting XML-formatted tool calls instead of using native function calling. " + + "This typically happens when your API provider does not fully support OpenAI's function/tool calling feature. " + + "Please verify that your API provider supports native tool calling, or try using a different provider." cline.consecutiveMistakeCount++ await cline.say("error", errorMessage) cline.userMessageContent.push({ type: "text", text: errorMessage }) @@ -335,7 +337,9 @@ export async function presentAssistantMessage(cline: Task) { const toolCallId = (block as any).id as string | undefined if (!toolCallId) { const errorMessage = - "Invalid tool call: missing tool_use.id. XML tool calls are no longer supported. Remove any XML tool markup (e.g. ...) and use native tool calling instead." + "Invalid tool call: the model's tool call is missing a required ID. " + + "This typically happens when your API provider does not fully support OpenAI's function/tool calling feature. " + + "Please verify that your API provider supports native tool calling, or try using a different provider." // Record a tool error for visibility/telemetry. Use the reported tool name if present. try { if ( diff --git a/src/core/tools/BaseTool.ts b/src/core/tools/BaseTool.ts index 7d574068a97..640b7c21411 100644 --- a/src/core/tools/BaseTool.ts +++ b/src/core/tools/BaseTool.ts @@ -142,7 +142,8 @@ export abstract class BaseTool { })() if (paramsText.includes("<") && paramsText.includes(">")) { throw new Error( - "XML tool calls are no longer supported. Use native tool calling (nativeArgs) instead.", + "The model is outputting XML-formatted tool calls instead of using native function calling. " + + "This typically happens when your API provider does not fully support OpenAI's function/tool calling feature.", ) } throw new Error("Tool call is missing native arguments (nativeArgs).")