Skip to content

fix: validate JSON before raw-embedding function call outputs in Responses API#2162

Merged
luispater merged 1 commit intorouter-for-me:devfrom
enieuwy:fix/responses-api-json-valid-check
Mar 16, 2026
Merged

fix: validate JSON before raw-embedding function call outputs in Responses API#2162
luispater merged 1 commit intorouter-for-me:devfrom
enieuwy:fix/responses-api-json-valid-check

Conversation

@enieuwy
Copy link
Copy Markdown
Contributor

@enieuwy enieuwy commented Mar 16, 2026

Summary

  • Adds json.Valid() check before using sjson.SetRaw for function call outputs in the Responses API translator, preventing non-JSON content from being embedded raw into the Gemini API request payload.

Problem

gjson.Parse() marks any string starting with { or [ as gjson.JSON, even when the content is not valid JSON. This causes sjson.SetRaw to embed non-JSON content directly into the Gemini request, producing 400 errors from Google's API.

Two known triggers:

  1. macOS plist outputdefaults read returns { "$archiver" = NSKeyedArchiver; ... } which starts with { but uses = instead of :
  2. Truncated tool results — clients like opencode summarize old results as [Old tool result content cleared] which starts with [

Fix

One-line change: add json.Valid([]byte(output.Raw)) guard before SetRaw. Non-JSON content falls through to sjson.Set which properly escapes it as a JSON string.

Fixes #2161

…onses 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 router-for-me#2161
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the stability of the Gemini API integration by addressing a critical issue where invalid JSON structures were being incorrectly processed. By implementing a pre-check for JSON validity, the system now prevents malformed data from causing API errors, ensuring that all function call outputs are correctly formatted before transmission. This change improves the reliability of the translation layer without altering the core logic for valid JSON payloads.

Highlights

  • JSON Validation: Introduced a json.Valid() check before raw-embedding function call outputs in the Responses API translator to prevent malformed JSON from being directly inserted into the Gemini API request payload.
  • Error Prevention: Resolved an issue where gjson.Parse() would incorrectly mark non-JSON strings (e.g., macOS plist output, truncated tool results) as valid JSON, leading to 400 errors from the Google Gemini API.
  • Robustness: Ensured that non-JSON content now correctly falls through to sjson.Set, which properly escapes it as a JSON string, enhancing the robustness of the API integration.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • internal/translator/gemini/openai/responses/gemini_openai-responses_request.go
    • Imported the encoding/json package.
    • Added a json.Valid() check to ensure that sjson.SetRaw is only used for genuinely valid JSON content.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly fixes a bug where non-JSON strings were being embedded as raw JSON, causing API errors. The addition of a json.Valid() check before using sjson.SetRaw is an effective solution.

I noticed a similar pattern at line 307 in the same file (internal/translator/gemini/openai/responses/gemini_openai-responses_request.go), where functionCall arguments are processed:

arguments := item.Get("arguments").String()
// ...
argsResult := gjson.Parse(arguments)
functionCall, _ = sjson.SetRaw(functionCall, "functionCall.args", argsResult.Raw)

This could be vulnerable to the same issue if the arguments string is not valid JSON. You might consider applying a similar validation there to improve robustness.

Copy link
Copy Markdown

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Verdict: Looks good

Clean, minimal fix for a real correctness issue. The gjson type-sniffing producing false positives for plist syntax and bracket-prefixed strings is a known foot-gun, and gating with json.Valid() is the right call.

What's good:

  • Single-line change, minimal blast radius
  • The fallthrough to sjson.Set (string-escaped) is the correct safe default
  • Both trigger cases (plist { and truncated [) are well documented in the PR description

Minor observations (non-blocking):

  • Consider whether a debug/trace-level log when the json.Valid guard rejects input would help future debugging of unexpected Gemini API payloads. Not required, but could save time if a third edge case surfaces.
  • The import of encoding/json just for json.Valid is fine; it's stdlib with zero overhead.

No bugs, no security concerns. Ship it.

@luispater luispater changed the base branch from main to dev March 16, 2026 10:42
@luispater luispater merged commit db63f9b into router-for-me:dev Mar 16, 2026
1 of 2 checks passed
haimichenha added a commit to haimichenha/CLIProxyAPI that referenced this pull request Mar 20, 2026
Includes bug fixes, new features (Codex plan support, Vertex API,
Amp integration, streaming keepalive, model alias enhancements),
CI/CD updates, and community contributions through PR router-for-me#2162.

Preserves custom config.yaml and cankao.txt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Responses API translator: tool outputs starting with { but not valid JSON are embedded raw, causing 400 from Gemini

3 participants