fix: retry when model returns empty response after tool execution#4982
Open
akashbangad wants to merge 2 commits intogoogle:mainfrom
Open
fix: retry when model returns empty response after tool execution#4982akashbangad wants to merge 2 commits intogoogle:mainfrom
akashbangad wants to merge 2 commits intogoogle:mainfrom
Conversation
Some models (notably Claude, and some Gemini preview models) occasionally return an empty content array (parts: []) after processing tool results. ADK's is_final_response() treats this as a valid completed turn because it only checks for the absence of function calls — not the presence of actual content. The agent loop stops and the user sees nothing. This adds a retry mechanism in BaseLlmFlow.run_async() that detects empty/meaningless final responses and re-prompts the model, up to a configurable maximum (default 2 retries) to prevent infinite loops. Closes google#3754 Related: google#3467, google#4090, google#3034
This was referenced Mar 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
Some models (notably Claude, and some Gemini preview models) return an empty content array (
parts: []) after processing tool results. ADK'sis_final_response()treats this as a valid completed turn because it only checks for the absence of function calls — not the presence of actual content. The agent loop stops and the user sees nothing.Observed with:
AnthropicLlm— afterrun_shell,computer_usetool resultsExample session history showing the bug:
Root Cause
In
BaseLlmFlow.run_async()(line 757):And
is_final_response()inevent.py:An event with
parts: []passes all these checks — no function calls, no function responses, not partial — sois_final_response()returnsTrueand the loop breaks.Fix
Added a retry mechanism in
BaseLlmFlow.run_async():_has_meaningful_content(event)— helper that checks if an event actually contains content worth showing (non-empty text, function calls, inline data, etc.)is_final_response()isTruebut the event has no meaningful content, the loop continues instead of breaking, re-prompting the model_MAX_EMPTY_RESPONSE_RETRIES = 2) prevents infinite loops if the model keeps returning empty responsesTests
Added 10 new tests in
test_empty_response_retry.py:_has_meaningful_contenttests (7):test_no_content—Nonecontent → not meaningfultest_empty_parts—parts: []→ not meaningfultest_only_empty_text_part—text=""→ not meaningfultest_only_whitespace_text_part—text=" \n "→ not meaningfultest_non_empty_text— actual text → meaningfultest_function_call— function call → meaningfultest_function_response— function response → meaningfulIntegration tests (3):
test_empty_response_retried_then_succeeds— empty response triggers retry, second call succeedstest_empty_response_stops_after_max_retries— stops after max retries to prevent infinite looptest_non_empty_response_not_retried— normal responses are not retriedAll 10 tests pass. All 356 pre-existing
flows/llm_flows/tests pass.Closes #3754
Related: #3467, #4090, #3034
🤖 Generated with Claude Code