Skip to content

fix: surface Gemini blocked/empty response reasons instead of generic error#12046

Draft
roomote-v0[bot] wants to merge 1 commit intomainfrom
fix/gemini-empty-response-handling
Draft

fix: surface Gemini blocked/empty response reasons instead of generic error#12046
roomote-v0[bot] wants to merge 1 commit intomainfrom
fix/gemini-empty-response-handling

Conversation

@roomote-v0
Copy link
Copy Markdown
Contributor

@roomote-v0 roomote-v0 bot commented Apr 2, 2026

Summary

This PR attempts to address Issue #12045. Feedback and guidance are welcome.

Problem

When the Gemini API returns an empty or blocked response (e.g., due to safety filters, recitation checks, or reasoning-only output), the handler silently produces no output. This causes Task.ts to fall into the generic "The language model did not provide any assistant messages" error path, giving no useful information about what actually went wrong.

Changes

1. Surface non-STOP finishReason in src/api/providers/gemini.ts

After the stream completes, if the Gemini API returned a non-STOP/non-MAX_TOKENS finishReason (such as SAFETY, RECITATION, PROHIBITED_CONTENT) and no content was produced, throw a descriptive error with the actual finish reason instead of silently yielding nothing.

2. Handle reasoning-only responses in src/api/providers/gemini.ts

When a thinking/reasoning model (like gemini-3.1-pro-preview) returns only reasoning content without actionable text or tool calls, yield a placeholder text chunk so that the downstream "no assistant messages" check is not triggered, allowing the retry logic to re-prompt the model.

Tests

Added 7 new test cases covering:

  • SAFETY finishReason with no content (throws descriptive error)
  • RECITATION finishReason with no content (throws descriptive error)
  • PROHIBITED_CONTENT finishReason with no content (throws descriptive error)
  • STOP finishReason with no content (does not throw)
  • SAFETY finishReason with content already produced (does not throw)
  • Reasoning-only response yields placeholder text
  • Reasoning + text response does NOT yield placeholder

All existing tests continue to pass.

Interactively review PR in Roo Code Cloud

… error

When the Gemini API returns a non-STOP finishReason (SAFETY, RECITATION,
PROHIBITED_CONTENT) and no content was produced, throw a descriptive error
with the actual finish reason instead of silently yielding nothing and
falling into the generic "no assistant messages" error path.

Also handle reasoning-only responses (thinking models like
gemini-3.1-pro-preview that return only reasoning without actionable
text/tool calls) by yielding a placeholder text so downstream retry
logic can re-prompt the model.

Closes #12045
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.

1 participant