-
Notifications
You must be signed in to change notification settings - Fork 2.7k
fix: 'NoneType' object is not iterable #3988
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: main
Are you sure you want to change the base?
Changes from all commits
f76096b
6d94ea8
684187c
1740e2e
af824e7
335e8a8
5b2d86c
ed4bed6
20e5b37
569e941
40fef41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,7 +125,7 @@ async def run_async( | |
|
|
||
| if not last_content: | ||
| return '' | ||
| merged_text = '\n'.join(p.text for p in last_content.parts if p.text) | ||
| merged_text = '\n'.join(p.text for p in (last_content.parts or []) if p.text) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This Since you are already modifying this code, it would be a great opportunity to refactor and reduce duplication. One approach could be to make |
||
| if isinstance(self.agent, LlmAgent) and self.agent.output_schema: | ||
| tool_result = self.agent.output_schema.model_validate_json( | ||
| merged_text | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| from google.adk.agents.invocation_context import InvocationContext | ||
| from google.adk.agents.llm_agent import Agent | ||
| from google.adk.models.llm_response import LlmResponse | ||
| from google.adk.sessions.in_memory_session_service import InMemorySessionService | ||
| from google.adk.tools.google_search_agent_tool import GoogleSearchAgentTool | ||
| from google.adk.tools.tool_context import ToolContext | ||
| from google.genai import types | ||
| from google.genai.types import Part | ||
| from pytest import mark | ||
|
|
||
| from .. import testing_utils | ||
|
|
||
| function_call_no_schema = Part.from_function_call( | ||
| name='tool_agent', args={'request': 'test1'} | ||
| ) | ||
|
|
||
|
|
||
| @mark.asyncio | ||
| async def test_run_async_handles_none_parts_in_response(): | ||
| """Verify run_async handles None parts in the response without crashing.""" | ||
|
|
||
| # Mock model for the tool_agent that returns content with parts=None | ||
| # This simulates the condition causing the TypeError | ||
| tool_agent_model = testing_utils.MockModel.create( | ||
| responses=[ | ||
| LlmResponse( | ||
| content=types.Content(parts=None), | ||
| ) | ||
| ] | ||
| ) | ||
|
|
||
| tool_agent = Agent( | ||
| name='tool_agent', | ||
| model=tool_agent_model, | ||
| ) | ||
|
|
||
| agent_tool = GoogleSearchAgentTool(agent=tool_agent) | ||
|
|
||
| session_service = InMemorySessionService() | ||
| session = await session_service.create_session( | ||
| app_name='test_app', user_id='test_user' | ||
| ) | ||
|
|
||
| invocation_context = InvocationContext( | ||
| invocation_id='invocation_id', | ||
| agent=tool_agent, | ||
| session=session, | ||
| session_service=session_service, | ||
| ) | ||
| tool_context = ToolContext(invocation_context=invocation_context) | ||
|
|
||
| # This should not raise TypeError: 'NoneType' object is not iterable | ||
| # It should ideally return an empty string or handle it gracefully | ||
| tool_result = await agent_tool.run_async( | ||
| args=function_call_no_schema.function_call.args, tool_context=tool_context | ||
| ) | ||
|
|
||
| assert tool_result == '' |
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.
I noticed that this
run_asyncmethod is missing a call toawait runner.close()after theasync with Aclosing(...)block (around line 125).The parent class
AgentToolincludes this call, and a comment there highlights its importance for resource cleanup:The absence of this call could lead to resource leaks. Please add
await runner.close()before theif not last_content:check.