[
https://issues.apache.org/jira/browse/CAMEL-23961?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Federico Mariani updated CAMEL-23961:
-------------------------------------
Attachment: OpenAIEmptyChoicesResponseTest.java
> 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
> Priority: Minor
> Labels: ai
> 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)