diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts
index 7f5862be154..7ce938ccef2 100644
--- a/src/core/assistant-message/presentAssistantMessage.ts
+++ b/src/core/assistant-message/presentAssistantMessage.ts
@@ -300,22 +300,27 @@ export async function presentAssistantMessage(cline: Task) {
// A tool_use block without an id is invalid and cannot be executed.
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."
+ const userFacingError =
+ "XML tool calls are no longer supported. Remove any XML tool markup (e.g. ...) and use native tool calling instead."
// Record a tool error for visibility/telemetry. Use the reported tool name if present.
try {
if (
typeof (cline as any).recordToolError === "function" &&
typeof (block as any).name === "string"
) {
- ;(cline as any).recordToolError((block as any).name as ToolName, errorMessage)
+ ;(cline as any).recordToolError((block as any).name as ToolName, userFacingError)
}
} catch {
// Best-effort only
}
cline.consecutiveMistakeCount++
- await cline.say("error", errorMessage)
- cline.userMessageContent.push({ type: "text", text: errorMessage })
+ await cline.say("error", userFacingError)
+ // Push comprehensive error with tool-use instructions so the model
+ // can self-correct on the next turn (see #11106).
+ cline.userMessageContent.push({
+ type: "text",
+ text: formatResponse.xmlToolCallError(),
+ })
cline.didAlreadyUseTool = true
break
}
diff --git a/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts b/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts
new file mode 100644
index 00000000000..ae632d32e90
--- /dev/null
+++ b/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts
@@ -0,0 +1,38 @@
+// npx vitest core/prompts/__tests__/responses-xml-tool-call-error.spec.ts
+
+import { formatResponse } from "../responses"
+
+describe("formatResponse.xmlToolCallError", () => {
+ it("should return a string containing the XML error explanation", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toContain("XML tool calls are no longer supported")
+ })
+
+ it("should include instruction to not embed XML tags in text", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toContain("Do NOT embed tool invocations as XML tags")
+ })
+
+ it("should include tool use instructions reminder", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toContain("Reminder: Instructions for Tool Use")
+ expect(result).toContain("native tool calling mechanism")
+ })
+
+ it("should include next steps guidance", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toContain("Next Steps")
+ expect(result).toContain("attempt_completion")
+ expect(result).toContain("ask_followup_question")
+ })
+
+ it("should include the [ERROR] prefix", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toMatch(/^\[ERROR\]/)
+ })
+
+ it("should include automated message notice", () => {
+ const result = formatResponse.xmlToolCallError()
+ expect(result).toContain("This is an automated message")
+ })
+})
diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts
index 60b5b4123ac..96bfa37bd99 100644
--- a/src/core/prompts/responses.ts
+++ b/src/core/prompts/responses.ts
@@ -54,6 +54,24 @@ Otherwise, if you have not completed the task and do not need additional informa
(This is an automated message, so do not respond to it conversationally.)`
},
+ xmlToolCallError: () => {
+ const instructions = getToolInstructionsReminder()
+
+ return `[ERROR] XML tool calls are no longer supported. The model produced XML-style tool markup (e.g. ...) instead of using the API's native tool calling mechanism.
+
+Do NOT embed tool invocations as XML tags in your text response. Instead, use the platform's built-in function/tool calling feature to invoke tools.
+
+${instructions}
+
+# Next Steps
+
+Please retry your previous action using proper native tool calls.
+If you have completed the user's task, use the attempt_completion tool.
+If you require additional information from the user, use the ask_followup_question tool.
+Otherwise, proceed with the next step of the task using native tool calls.
+(This is an automated message, so do not respond to it conversationally.)`
+ },
+
tooManyMistakes: (feedback?: string) =>
JSON.stringify({
status: "guidance",
diff --git a/src/core/tools/BaseTool.ts b/src/core/tools/BaseTool.ts
index 7d574068a97..1a27d4f7bea 100644
--- a/src/core/tools/BaseTool.ts
+++ b/src/core/tools/BaseTool.ts
@@ -142,10 +142,15 @@ 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.",
+ "XML tool calls are no longer supported. " +
+ "Do not embed tool invocations as XML tags in your text response. " +
+ "Use the platform's native tool calling mechanism (nativeArgs) instead.",
)
}
- throw new Error("Tool call is missing native arguments (nativeArgs).")
+ throw new Error(
+ "Tool call is missing native arguments (nativeArgs). " +
+ "Use the platform's native tool calling mechanism to invoke tools.",
+ )
}
} catch (error) {
console.error(`Error parsing parameters:`, error)