diff --git a/src/agents/extensions/models/any_llm_model.py b/src/agents/extensions/models/any_llm_model.py index 8a12fdbd9c..3a10c03f95 100644 --- a/src/agents/extensions/models/any_llm_model.py +++ b/src/agents/extensions/models/any_llm_model.py @@ -609,6 +609,14 @@ async def _get_response_via_chat( prompt=prompt, ) + if not response.choices: + provider_error = getattr(response, "error", None) + error_details = f": {provider_error}" if provider_error is not None else "" + raise ModelBehaviorError( + f"ChatCompletion response has no choices (possible provider error payload)" + f"{error_details}" + ) + message: ChatCompletionMessage | None = None first_choice: Choice | None = None if response.choices: diff --git a/tests/models/test_any_llm_model.py b/tests/models/test_any_llm_model.py index 3e02b28ebd..a0f550298c 100644 --- a/tests/models/test_any_llm_model.py +++ b/tests/models/test_any_llm_model.py @@ -659,6 +659,37 @@ async def test_any_llm_chat_path_content_filter_keeps_real_content(monkeypatch) assert response.output[0].content[0].text == "here is the answer" +@pytest.mark.allow_call_model_methods +@pytest.mark.asyncio +async def test_any_llm_chat_path_rejects_empty_choices(monkeypatch) -> None: + provider = FakeAnyLLMProvider( + supports_responses=False, + chat_response=ChatCompletion( + id="chatcmpl_empty", + created=0, + model="fake-model", + object="chat.completion", + choices=[], + ), + ) + module, _create_calls = _import_any_llm_module(monkeypatch, provider) + + model = module.AnyLLMModel(model="openrouter/openai/gpt-5.4-mini") + with pytest.raises(ModelBehaviorError, match="ChatCompletion response has no choices"): + await model.get_response( + system_instructions=None, + input="hi", + model_settings=ModelSettings(), + tools=[], + output_schema=None, + handoffs=[], + tracing=ModelTracing.DISABLED, + previous_response_id=None, + conversation_id=None, + prompt=None, + ) + + @pytest.mark.allow_call_model_methods @pytest.mark.asyncio @pytest.mark.parametrize(