Skip to content

[Bug] 流式响应中 tool_use.id 包含非法字符,导致 Claude Code 后续请求返回 400 #1872

@aihongyang32-cpu

Description

@aihongyang32-cpu

客户端使用 Claude Code(claude-cli/2.1.69),上游走 Gemini/Vertex 后端时,流式响应翻译器生成的 tool_use.id 不符合 Claude API 要求的正则 ^[a-zA-Z0-9_-]+$

根因internal/translator/gemini/claude/gemini_claude_response.go 第 224 行:

data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("%s-%d-%d", fcName, time.Now().UnixNano(), atomic.AddUint64(&toolUseIDCounter, 1)))

生成的 ID 格式为 {函数名}-{时间戳}-{计数器},例如- mcp__serena__list_dir-1741196414123456789-1合法只含 a-z、_、-- 但如果函数名含有点号等特殊字符( fs.readFile),ID 就变成 fs.readFile-1741196414123456789-1不符合 ^[a-zA-Z0-9_-]+$

Claude Code 会保存这些 ID并在后续请求的 tool_use_id 字段中回传导致上游 Claude API 校验失败返回400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.1.content.2.tool_use.id: String should match pattern '^[a-zA-Z0-9_-]+$'"}}

注意非流式路径ConvertGeminiResponseToClaudeNonStream 342 使用的是 fmt.Sprintf("tool_%d", toolIDCounter),不会触发此问题期望行为

tool_use.id 应只包含 ^[a-zA-Z0-9_-]+$ 范围内的字符 claude_gemini_request.go 中使用的 toolu_ 前缀格式保持一致建议修复

将第 224 行替换为安全的 ID 格式例如sanitizedName := regexp.MustCompile(`[^a-zA-Z0-9_-]`).ReplaceAllString(fcName, "_")
data, _ = sjson.Set(data, "content_block.id", fmt.Sprintf("toolu_%s_%d_%d", sanitizedName, time.Now().UnixNano(), atomic.AddUi

Metadata

Metadata

Assignees

No one assigned

    Labels

    pendingWaiting for research

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions