diff --git a/src/strands/models/gemini.py b/src/strands/models/gemini.py index cf7cc604a..45f7f4e18 100644 --- a/src/strands/models/gemini.py +++ b/src/strands/models/gemini.py @@ -426,6 +426,8 @@ async def stream( yield self._format_chunk({"chunk_type": "content_start", "data_type": "text"}) tool_used = False + candidate = None + event = None async for event in response: candidates = event.candidates candidate = candidates[0] if candidates else None @@ -455,7 +457,8 @@ async def stream( "data": "TOOL_USE" if tool_used else (candidate.finish_reason if candidate else "STOP"), } ) - yield self._format_chunk({"chunk_type": "metadata", "data": event.usage_metadata}) + if event: + yield self._format_chunk({"chunk_type": "metadata", "data": event.usage_metadata}) except genai.errors.ClientError as error: if not error.message: diff --git a/tests/strands/models/test_gemini.py b/tests/strands/models/test_gemini.py index c552a892a..08be9188d 100644 --- a/tests/strands/models/test_gemini.py +++ b/tests/strands/models/test_gemini.py @@ -566,6 +566,25 @@ async def test_stream_response_none_candidates(gemini_client, model, messages, a assert tru_chunks == exp_chunks +@pytest.mark.asyncio +async def test_stream_response_empty_stream(gemini_client, model, messages, agenerator, alist): + """Test that empty stream doesn't raise UnboundLocalError. + + When the stream yields no events, the candidate variable must be initialized + to None to avoid UnboundLocalError when referenced in message_stop chunk. + """ + gemini_client.aio.models.generate_content_stream.return_value = agenerator([]) + + tru_chunks = await alist(model.stream(messages)) + exp_chunks = [ + {"messageStart": {"role": "assistant"}}, + {"contentBlockStart": {"start": {}}}, + {"contentBlockStop": {}}, + {"messageStop": {"stopReason": "end_turn"}}, + ] + assert tru_chunks == exp_chunks + + @pytest.mark.asyncio async def test_stream_response_throttled_exception(gemini_client, model, messages): gemini_client.aio.models.generate_content_stream.side_effect = genai.errors.ClientError(