diff --git a/open-sse/translator/helpers/claudeHelper.ts b/open-sse/translator/helpers/claudeHelper.ts index b30ad23eac..9b77a12594 100644 --- a/open-sse/translator/helpers/claudeHelper.ts +++ b/open-sse/translator/helpers/claudeHelper.ts @@ -126,6 +126,15 @@ export function prepareClaudeRequest(body, provider = null) { } } + // Pass 1.4: Filter out tool_use blocks with empty names (causes Claude 400 error) + for (const msg of filtered) { + if (msg.role === "assistant" && Array.isArray(msg.content)) { + msg.content = msg.content.filter( + (block) => block.type !== "tool_use" || (block.name && block.name.trim()) + ); + } + } + // Pass 1.5: Fix tool_use/tool_result ordering // Each tool_use must have tool_result in the NEXT message (not same message with other content) filtered = fixToolUseOrdering(filtered); diff --git a/open-sse/translator/request/openai-to-claude.ts b/open-sse/translator/request/openai-to-claude.ts index b7004276c0..cec2430ef2 100644 --- a/open-sse/translator/request/openai-to-claude.ts +++ b/open-sse/translator/request/openai-to-claude.ts @@ -228,7 +228,10 @@ function getContentBlocksFromMessage(msg, toolNameMap = new Map()) { }); } else if (part.type === "tool_use") { // Tool name already has prefix from tool declarations, keep as-is - blocks.push({ type: "tool_use", id: part.id, name: part.name, input: part.input }); + // CRITICAL: Skip tool_use blocks with empty name (causes Claude 400 error) + if (part.name && part.name.trim()) { + blocks.push({ type: "tool_use", id: part.id, name: part.name, input: part.input }); + } } } } else if (msg.content) { @@ -241,8 +244,12 @@ function getContentBlocksFromMessage(msg, toolNameMap = new Map()) { if (msg.tool_calls && Array.isArray(msg.tool_calls)) { for (const tc of msg.tool_calls) { if (tc.type === "function") { + // CRITICAL: Skip tool_calls with empty function name (causes Claude 400 error) + const fnName = tc.function?.name; + if (!fnName || !fnName.trim()) continue; + // Apply prefix to tool name - const toolName = CLAUDE_OAUTH_TOOL_PREFIX + tc.function.name; + const toolName = CLAUDE_OAUTH_TOOL_PREFIX + fnName; blocks.push({ type: "tool_use", id: tc.id,