From b24ae742167313d18ef960310935939603b0b4c9 Mon Sep 17 00:00:00 2001 From: enieuwy Date: Mon, 16 Mar 2026 15:29:18 +0800 Subject: [PATCH] fix: validate JSON before raw-embedding function call outputs in Responses API gjson.Parse() marks any string starting with { or [ as gjson.JSON type, even when the content is not valid JSON (e.g. macOS plist format, truncated tool results). This caused sjson.SetRaw to embed non-JSON content directly into the Gemini API request payload, producing 400 errors. Add json.Valid() check before using SetRaw to ensure only actually valid JSON is embedded raw. Non-JSON content now falls through to sjson.Set which properly escapes it as a JSON string. Fixes #2161 --- .../gemini/openai/responses/gemini_openai-responses_request.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/translator/gemini/openai/responses/gemini_openai-responses_request.go b/internal/translator/gemini/openai/responses/gemini_openai-responses_request.go index 463203a7..44b78346 100644 --- a/internal/translator/gemini/openai/responses/gemini_openai-responses_request.go +++ b/internal/translator/gemini/openai/responses/gemini_openai-responses_request.go @@ -1,6 +1,7 @@ package responses import ( + "encoding/json" "strings" "github.com/router-for-me/CLIProxyAPI/v6/internal/translator/gemini/common" @@ -340,7 +341,7 @@ func ConvertOpenAIResponsesRequestToGemini(modelName string, inputRawJSON []byte // Set the raw JSON output directly (preserves string encoding) if outputRaw != "" && outputRaw != "null" { output := gjson.Parse(outputRaw) - if output.Type == gjson.JSON { + if output.Type == gjson.JSON && json.Valid([]byte(output.Raw)) { functionResponse, _ = sjson.SetRaw(functionResponse, "functionResponse.response.result", output.Raw) } else { functionResponse, _ = sjson.Set(functionResponse, "functionResponse.response.result", outputRaw)