Federico Mariani created CAMEL-23961:
----------------------------------------
Summary: camel-openai: empty choices array from an
OpenAI-compatible provider fails with raw IndexOutOfBoundsException
Key: CAMEL-23961
URL: https://issues.apache.org/jira/browse/CAMEL-23961
Project: Camel
Issue Type: Bug
Components: camel-openai
Affects Versions: 4.21.0
Reporter: Federico Mariani
Attachments: OpenAIEmptyChoicesResponseTest.java
Defensive-hardening bug: a chat completion response with an empty {{choices}}
array makes {{OpenAIProducer.processNonStreamingSimple}} and
{{processNonStreamingAgentic}} fail with a raw exception, because
{{response.choices().get(0)}} is dereferenced unguarded:
{noformat}
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
{noformat}
which gives the user no hint about what actually went wrong. Notably
{{setResponseHeaders}} in the same class already guards
{{!response.choices().isEmpty()}}, and {{OpenAIToolExecutionProducer}} logs and
skips — the unguarded accesses are inconsistent with the component's own
defensive code.
Evidence that empty {{choices}} payloads occur in the OpenAI-compatible
ecosystem: Azure OpenAI streaming sends a first chunk with an empty {{choices}}
array carrying content-filter results (this exact IndexError bit LangChain
#6462, Semantic Kernel #3650 and Langfuse #2833), and OpenRouter documents a
final usage-only streaming chunk with an empty {{choices}} array. For the
*non-streaming* path no mainstream provider is documented to return 200 with
empty choices, so this is hardening against misbehaving shims/proxies rather
than a named provider — priced accordingly (Minor). In camel-openai's streaming
path the chunks are handed to the user's iterator, so only the non-streaming
accesses are the component's responsibility.
Reproducer attached ({{OpenAIEmptyChoicesResponseTest}}, hand-crafted provider
response via {{camel-test-infra-openai-mock}}'s {{thenRespondWith}}); it fails
on current main.
h3. Suggested fix
Validate {{response.choices()}} before access and throw a descriptive exception
(e.g. {{CamelExchangeException("OpenAI response contained no choices",
exchange)}}), in both the simple and agentic paths.
_This issue was drafted by Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)