You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: surface Gemini blocked/empty response reasons instead of generic 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
error: "Gemini response blocked: finishReason=SAFETY. The model did not produce any content. This may be caused by safety filters, content policy, or recitation checks.",
294
+
}),
295
+
)
296
+
})
297
+
298
+
it("should throw a descriptive error when finishReason is RECITATION and no content was produced",async()=>{
error: "Gemini response blocked: finishReason=RECITATION. The model did not produce any content. This may be caused by safety filters, content policy, or recitation checks.",
322
+
}),
323
+
)
324
+
})
325
+
326
+
it("should throw a descriptive error when finishReason is PROHIBITED_CONTENT",async()=>{
error: "Gemini response blocked: finishReason=PROHIBITED_CONTENT. The model did not produce any content. This may be caused by safety filters, content policy, or recitation checks.",
350
+
}),
351
+
)
352
+
})
353
+
354
+
it("should NOT throw when finishReason is STOP even without content",async()=>{
`Gemini response blocked: finishReason=${finishReason}. The model did not produce any content. This may be caused by safety filters, content policy, or recitation checks.`,
316
+
)
317
+
}
318
+
319
+
// When a thinking/reasoning model (e.g. gemini-3.1-pro-preview)
320
+
// returns only reasoning content without any actionable text or
321
+
// tool calls, yield a minimal text chunk so that the downstream
322
+
// "no assistant messages" check in Task.ts is not triggered. This
323
+
// gives the retry logic a chance to re-prompt the model instead of
324
+
// treating it as a hard failure.
325
+
if(!hasContent&&hasReasoning){
326
+
yield{
327
+
type: "text",
328
+
text: "[The model produced reasoning but no actionable response. Retrying...]",
0 commit comments