-
-
Notifications
You must be signed in to change notification settings - Fork 539
fix: prevent Gemini 400 errors for empty properties and custom-only tools #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
fix: prevent Gemini 400 errors for empty properties and custom-only tools #319
Conversation
…ools
1. Add placeholder for empty OBJECT properties in toGeminiSchema()
- Gemini rejects properties: {} with 400 Bad Request
2. Create function from custom before custom is deleted
- Prevents schema loss when tool only has 'custom' format
3. Pass schemas through toGeminiSchema() in wrapToolsAsFunctionDeclarations()
- Ensures all schemas get the empty properties fix
WalkthroughChanges to Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro Cache: Disabled due to data retention organization setting Knowledge base: Disabled due to data retention organization setting 📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)src/plugin/transform/gemini.ts (3)
🔇 Additional comments (9)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile OverviewGreptile SummaryThis PR fixes three related issues causing 400 Bad Request errors when using Gemini models with OpenCode/OhMyOpenCode. Problems Fixed1. Empty properties object rejection (lines 139-152)
2. Schema loss for custom-only tools (lines 371-378)
3. Schema transformation bypass in wrapper (lines 584-589, 625)
Changes Summary
The fixes ensure all tool schemas are Gemini-compatible before being sent to the API, preventing 400 errors. Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as OpenCode/OhMyOpenCode
participant Transform as applyGeminiTransforms
participant Normalize as normalizeGeminiTools
participant Wrap as wrapToolsAsFunctionDeclarations
participant Schema as toGeminiSchema
participant Gemini as Gemini API
Client->>Transform: Request with tools
Transform->>Normalize: Normalize tool formats
Note over Normalize: For each tool
Normalize->>Schema: Transform schema (line 325)
Schema->>Schema: Convert types to uppercase
Schema->>Schema: Remove unsupported fields
alt Empty properties detected
Schema->>Schema: Add _placeholder property (lines 139-152)
end
Schema-->>Normalize: Transformed schema
alt Tool has custom but no function
Normalize->>Normalize: Create function from custom (lines 371-378)
end
Normalize->>Normalize: Delete custom wrapper (line 394)
Normalize-->>Transform: Normalized tools
Transform->>Wrap: Wrap in functionDeclarations
Note over Wrap: For each tool
Wrap->>Schema: Transform parameters (lines 584, 625)
alt Empty properties in fallback
Schema->>Schema: Add _placeholder to fallback schema
end
Schema-->>Wrap: Gemini-compatible parameters
Wrap->>Wrap: Build functionDeclarations array
Wrap-->>Transform: Wrapped tools
Transform-->>Client: Transformed request
Client->>Gemini: Send request with valid schemas
Gemini-->>Client: Success (no 400 errors)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 file reviewed, 2 comments
| name, | ||
| description, | ||
| parameters: schema, | ||
| parameters: toGeminiSchema(schema) as Record<string, unknown>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check that test at gemini.test.ts:1087 still passes - it expects { type: "OBJECT", properties: {} } to remain unchanged, but this will now add the _placeholder property via toGeminiSchema()
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin/transform/gemini.ts
Line: 625:625
Comment:
check that test at `gemini.test.ts:1087` still passes - it expects `{ type: "OBJECT", properties: {} }` to remain unchanged, but this will now add the `_placeholder` property via `toGeminiSchema()`
How can I resolve this? If you propose a fix, please make it concise.| description: "Placeholder parameter. Always pass true.", | ||
| }, | ||
| }; | ||
| result.required = ["_placeholder"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unconditionally overwrites any existing required array - though unlikely with empty properties, consider preserving existing required items if they exist
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin/transform/gemini.ts
Line: 151:151
Comment:
unconditionally overwrites any existing `required` array - though unlikely with empty properties, consider preserving existing required items if they exist
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
Summary
Fixes 400 Bad Request errors when using tools with OpenCode/OhMyOpenCode and Gemini models.
Problems Fixed
1. Gemini rejects empty properties object
Tools with
properties: {}(liketodoread) cause 400 Bad Request because Gemini's strict protobuf validation rejects empty properties.Fix: Add placeholder property when properties object is empty in
toGeminiSchema().2. Schema loss when tool has 'custom' but no 'function'
When a tool only has 'custom' format (no 'function'), the schema was being set on 'custom.input_schema' but then 'custom' was deleted, leaving the tool with no schema.
Fix: Create 'function' from 'custom' before 'custom' is deleted.
3. wrapToolsAsFunctionDeclarations bypasses toGeminiSchema
Schemas extracted in
wrapToolsAsFunctionDeclarationswere not being transformed throughtoGeminiSchema(), causing empty properties to slip through.Fix: Call
toGeminiSchema()on all extracted schemas.Testing
Tested with oh-my-opencode using Gemini 3 Pro via Antigravity:
todoreadtool (no parameters) now works