AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Provider Errors Returned In A 200 Response Body Are Never Classified

langchain-openai fails to classify errors embedded in HTTP 200 responses from OpenAI-compatible gateways. Non-streaming invoke raises a bare ValueError, streaming raises an unclassified openai.APIError, and Responses API raises ValueError. This prevents callers from accessing is_retryable and other ModelError attributes, breaking retry logic and potentially causing silent degradation.

highConfidence 92%LangChainAffected V1.6.2

Origin Analysis

In langchain-openai, the _create_chat_result method raises ValueError(response_dict.get('error')) directly instead of routing the error through _handle_openai_api_error. Streaming paths receive an openai.APIError with no status_code because the SDK only sets it from HTTP status, not from the error body. Consequently, _handle_openai_api_error cannot classify these errors, leaving them without is_retryable or ModelError type.
1. Run the provided fake gateway Python script that returns HTTP 200 with body {'error': {'code': 502, 'message': 'Provider returned error', 'type': 'server_error'}} for both streaming and non-streaming requests.\n2. Instantiate ChatOpenAI with base_url pointing to the fake gateway and max_retries=0.\n3. Call llm.invoke('hi') and observe a ValueError with the error dictionary but no is_retryable attribute.\n4. Call llm.stream('hi') and observe an openai.APIError with no status_code and no is_retryable attribute.

Fixing Code Block

Edge Case Audit

This fix changes error types from ValueError to ModelError subclasses, which may break existing code that catches ValueError for these cases. The existing test test__construct_lc_result_from_responses_api_error_handling expects ValueError and must be updated to expect ModelError. The openai.APIError constructor signature may vary between SDK versions; if the SDK changes, the helper method may need adjustment. In concurrent environments, ensure that the status_code extraction and assignment are thread-safe (the current approach mutates the exception object, which is local to the thread). Rollback recommendation: revert to the original raise ValueError line if unexpected regressions occur, but be aware that error classification will be lost.

Ecosystem Topology