BerriAI/litellm · error · HTTPException
Braintrust API error: {e.response.text}
Error message
Braintrust API error: {e.response.text} What it means
Raised during iteration of a sync text-completion stream in LiteLLM's OpenAI handler. Even after the stream is established, exceptions can occur while yielding parsed chunks (malformed SSE events, mid-stream connection resets, provider aborts). The for-loop over CustomStreamWrapper catches these and re-wraps them as OpenAIError with status, headers, and text. 'error_text' as the message means the underlying exception lacked a .text attribute and fell back to str(e).
Source
Thrown at cookbook/litellm_proxy_server/braintrust_prompt_wrapper_server.py:211
)
# Call Braintrust API
braintrust_url = f"https://api.braintrust.dev/v1/prompt/{prompt_id}"
headers = {
"Authorization": f"Bearer {braintrust_token}",
"Accept": "application/json",
}
print(f"headers: {headers}")
print(f"braintrust_url: {braintrust_url}")
print(f"braintrust_token: {braintrust_token}")
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(braintrust_url, headers=headers)
response.raise_for_status()
braintrust_data = response.json()
except httpx.HTTPStatusError as e:
raise HTTPException(
status_code=e.response.status_code,
detail=f"Braintrust API error: {e.response.text}",
)
except httpx.RequestError as e:
raise HTTPException(
status_code=502,
detail=f"Failed to connect to Braintrust API: {str(e)}",
)
except json.JSONDecodeError as e:
raise HTTPException(
status_code=502,
detail=f"Failed to parse Braintrust API response: {str(e)}",
)
print(f"braintrust_data: {braintrust_data}")
# Transform the response
try:
transformed_data = transform_braintrust_response(braintrust_data)View on GitHub (pinned to 6c2dcb801b)
Solutions
- Wrap the entire chunk-consuming loop (not just the call) in try/except for OpenAIError.
- Enable num_retries and note that mid-stream retries restart the request; accumulate partial content and decide whether to re-request.
- Set explicit stream_timeout to fail fast on stalled streams.
- If mid-stream aborts recur, check intermediary proxies for idle-connection timeouts and enable heartbeat/keep-alive.
Example fix
# before
for chunk in litellm.text_completion(model=..., prompt=..., stream=True):
process(chunk)
# after
try:
for chunk in litellm.text_completion(model=..., prompt=..., stream=True):
process(chunk)
except litellm.exceptions.OpenAIError as e:
logger.error("stream failed: %s (%s)", e.message, e.status_code) Defensive patterns
Strategy: try-catch
Type guard
from litellm.exceptions import OpenAIError
def is_midstream_failure(e: BaseException) -> bool:
return isinstance(e, OpenAIError) Try / catch
from litellm.exceptions import OpenAIError
partial = []
try:
for chunk in litellm.text_completion(model=..., prompt=..., stream=True):
partial.append(chunk.choices[0].get("text", ""))
except OpenAIError as e:
logger.warning("stream died after %d chars: %s", len("".join(partial)), e.message)
raise Prevention
- Wrap the whole consumption loop, not just the call site, in try/except.
- Accumulate partial output so a mid-stream failure is recoverable.
- Set stream_timeout and check proxy idle-timeouts for long generations.
When it happens
Trigger: Streaming with stream=True when the connection drops mid-stream, the provider sends an error event partway through, or a chunk fails schema parsing inside CustomStreamWrapper. Also triggered if the stream contains non-JSON SSE data lines.
Common situations: Long-running streams over unstable networks; providers that abort generation on content policy triggers; load balancers killing idle SSE connections; partial responses after long generation times.
Related errors
- Failed to connect to Braintrust API: {str(e)}
- Failed to parse Braintrust API response: {str(e)}
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
- No Braintrust API token provided. Pass via Authorization hea
- Failed to transform Braintrust response: {str(e)}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/8b631a22df92ff98.
Report an issue: GitHub.