From 2eb0c283e9a3f68ac5c1a874314710c495e46f72 Mon Sep 17 00:00:00 2001 From: Jiajun Xie Date: Tue, 17 Mar 2026 13:25:08 +0800 Subject: [PATCH 1/2] fix(providers): handle empty choices in custom provider response --- nanobot/providers/custom_provider.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nanobot/providers/custom_provider.py b/nanobot/providers/custom_provider.py index e177e55..4bdeb54 100644 --- a/nanobot/providers/custom_provider.py +++ b/nanobot/providers/custom_provider.py @@ -54,6 +54,11 @@ class CustomProvider(LLMProvider): return LLMResponse(content=f"Error: {e}", finish_reason="error") def _parse(self, response: Any) -> LLMResponse: + if not response.choices: + return LLMResponse( + content="Error: API returned empty choices. This may indicate a temporary service issue or an invalid model response.", + finish_reason="error" + ) choice = response.choices[0] msg = choice.message tool_calls = [ From 49fc50b1e623ee3a03a6e86b2dd6e90d956aaae2 Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Tue, 17 Mar 2026 06:20:19 +0000 Subject: [PATCH 2/2] test(custom): cover empty choices response handling --- tests/test_custom_provider.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/test_custom_provider.py diff --git a/tests/test_custom_provider.py b/tests/test_custom_provider.py new file mode 100644 index 0000000..463affe --- /dev/null +++ b/tests/test_custom_provider.py @@ -0,0 +1,13 @@ +from types import SimpleNamespace + +from nanobot.providers.custom_provider import CustomProvider + + +def test_custom_provider_parse_handles_empty_choices() -> None: + provider = CustomProvider() + response = SimpleNamespace(choices=[]) + + result = provider._parse(response) + + assert result.finish_reason == "error" + assert "empty choices" in result.content