Skip to content

fix(antigravity): sanitize request.contents to remove invalid metadata entries#1326

Closed
HaD0Yun wants to merge 1 commit intorouter-for-me:mainfrom
HaD0Yun:fix/gemini-invalid-json-payload-v2
Closed

fix(antigravity): sanitize request.contents to remove invalid metadata entries#1326
HaD0Yun wants to merge 1 commit intorouter-for-me:mainfrom
HaD0Yun:fix/gemini-invalid-json-payload-v2

Conversation

@HaD0Yun
Copy link

@HaD0Yun HaD0Yun commented Jan 30, 2026

Summary

  • Adds sanitizeRequestContents() function to filter invalid content entries before sending to Antigravity/Gemini API
  • Prevents "Invalid JSON payload" errors when conversation history contains malformed entries

The Problem

When conversation history is malformed or contains previous request objects as message entries, the Antigravity/Gemini API returns errors like:

Invalid JSON payload received. Unknown name "safetySettings" at 'request.contents[15]'
Invalid JSON payload received. Unknown name "model" at 'request.contents[15]'
Invalid JSON payload received. Unknown name "userAgent" at 'request.contents[15]'
Invalid JSON payload received. Unknown name "systemInstruction" at 'request.contents[15]'

The Fix

This PR adds a sanitization step in buildRequest() that:

  1. Iterates through all entries in request.contents
  2. Drops any entry containing request-level metadata fields instead of proper message content
  3. Logs a warning when invalid entries are dropped

Invalid fields filtered: safetySettings, model, userAgent, requestType, requestId, sessionId, systemInstruction, toolConfig, generationConfig, project, request, contents

Valid content entries should only contain: role, parts

Testing

  • Added comprehensive unit tests for sanitizeRequestContents()
  • All existing tests pass
  • Docker image rebuilt and tested locally

…a entries

When conversation history is malformed or contains previous request objects
as message entries, the Antigravity/Gemini API returns 'Invalid JSON payload'
errors like: Unknown name 'safetySettings' at 'request.contents[15]'

This fix adds sanitizeRequestContents() that filters out any content entries
containing request-level metadata fields (safetySettings, model, userAgent,
requestType, requestId, sessionId, systemInstruction, toolConfig, etc.)
before sending to the upstream API.

Fixes invalid content entries being passed through that contain full request
objects instead of proper message content (role + parts).
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @HaD0Yun, 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 robustness of API requests to the Antigravity/Gemini API by implementing a sanitization mechanism for conversation history. It addresses a recurring issue where malformed entries containing request-level metadata fields in the request.contents array would lead to API errors. The new logic ensures that only valid message content is transmitted, preventing payload rejections and improving overall system stability.

Highlights

  • New Sanitization Function: Introduced sanitizeRequestContents() to filter out invalid metadata from API request payloads before sending them to the Antigravity/Gemini API.
  • Error Prevention: Prevents "Invalid JSON payload" errors from the Antigravity/Gemini API by removing malformed conversation history entries that contain request-level metadata.
  • Targeted Filtering: Specifically removes fields such as safetySettings, model, userAgent, systemInstruction, and other request-level metadata from request.contents, ensuring only valid message content remains.
  • Comprehensive Testing: Includes a new dedicated unit test file (antigravity_executor_test.go) with various test cases to validate the correctness and robustness of the sanitizeRequestContents() function.

🧠 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.

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
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

The pull request introduces a sanitizeRequestContents function to filter invalid entries from the request.contents field, preventing Invalid JSON payload errors from the Antigravity/Gemini API. This is a good improvement for robustness. The changes include adding the function call in buildRequest and implementing the sanitization logic, along with comprehensive unit tests. Overall, the solution addresses the problem effectively.

}
newContentsJSON += "]"

result, _ := sjson.SetRawBytes(payload, contentsPath, []byte(newContentsJSON))
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The error returned by sjson.SetRawBytes is currently ignored. While sjson is generally robust, it's a good practice to handle potential errors, especially when modifying a critical payload. If SetRawBytes fails, the function will return the original, potentially invalid, payload without any indication of an issue, which could lead to the very errors this function aims to prevent.

result, err := sjson.SetRawBytes(payload, contentsPath, []byte(newContentsJSON))
if err != nil {
	log.Errorf("sanitizeRequestContents: failed to set raw bytes for contents: %v", err)
	return payload // Return original payload on error, or handle as appropriate
}

Comment on lines +1657 to +1664
newContentsJSON := "["
for i, content := range validContents {
if i > 0 {
newContentsJSON += ","
}
newContentsJSON += content.Raw
}
newContentsJSON += "]"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Reconstructing the newContentsJSON string by concatenating content.Raw in a loop can be inefficient for very large contents arrays. While gjson.Result.Raw provides the raw JSON, repeatedly concatenating strings can lead to multiple memory allocations. Consider building a slice of interface{} or map[string]interface{} from validContents and then marshaling it once to JSON, or exploring if sjson offers a more direct way to replace an array with a slice of gjson.Result objects.

}

for i, content := range contentsResult.Array() {
invalidFields := []string{"safetySettings", "model", "userAgent", "requestType", "requestId", "sessionId", "systemInstruction", "toolConfig", "generationConfig", "project", "request", "contents"}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The invalidFields slice is created inside the loop for each content entry. This leads to redundant allocations and can be inefficient. It should be defined once outside this inner loop.

Suggested change
invalidFields := []string{"safetySettings", "model", "userAgent", "requestType", "requestId", "sessionId", "systemInstruction", "toolConfig", "generationConfig", "project", "request", "contents"}
invalidFields := []string{"safetySettings", "model", "userAgent", "requestType", "requestId", "sessionId", "systemInstruction", "toolConfig", "generationConfig", "project", "request", "contents"}
for _, field := range invalidFields {

@luispater
Copy link
Collaborator

Please provide a payload to verify this PR. I believe these fields are all valid and do not require any additional removal.

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.

2 participants