[ 
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)

Reply via email to