BerriAI/litellm · error · HTTPException
Failed to parse Braintrust API response: {str(e)}
Error message
Failed to parse Braintrust API response: {str(e)} What it means
A guard inside OpenAI text-completion-to-chat response conversion: when converting a raw TextCompletionResponse into LiteLLM's ModelResponse format, the transform requires both a non-None response_object and model_response_object. If either is None (e.g. the caller passed no response dict, or an internal path failed to initialize the target ModelResponse), a ValueError with the generic message 'Error in response object format' is raised. It indicates a malformed or missing payload rather than an HTTP failure.
Source
Thrown at cookbook/litellm_proxy_server/braintrust_prompt_wrapper_server.py:221
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)
print(f"transformed_data: {transformed_data}")
return JSONResponse(content=transformed_data)
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Failed to transform Braintrust response: {str(e)}",
)
@app.get("/health")View on GitHub (pinned to 6c2dcb801b)
Solutions
- Log the raw HTTP response body (set LITELLM_LOG=DEBUG) to see what the provider actually returned.
- If using a custom api_base/proxy, verify it returns an OpenAI-spec completions JSON body with a choices array.
- Reproduce with litellm.text_completion() to confirm the raw path works, isolating the conversion layer.
- Upgrade litellm to the latest patch release in case a provider response-schema change was fixed.
Example fix
// not a caller-fixable error; capture the raw payload for diagnosis # before resp = litellm.completion(model="openai/gpt-3.5-turbo-instruct", messages=[...]) # after import litellm, logging litellm.suppress_debug_info = True logging.basicConfig(level=logging.DEBUG) resp = litellm.completion(model="openai/gpt-3.5-turbo-instruct", messages=[...]) # inspect raw body in debug logs
Defensive patterns
Strategy: validation
Validate before calling
def is_valid_text_completion_body(body: dict) -> bool:
return isinstance(body, dict) and isinstance(body.get("choices"), list) and len(body["choices"]) > 0 Try / catch
try:
resp = litellm.completion(model="openai/gpt-3.5-turbo-instruct", messages=[...])
except ValueError as e:
if "Error in response object format" in str(e):
logger.error("provider returned malformed/empty body; capture raw response with LITELLM_LOG=DEBUG")
raise Prevention
- Run with LITELLM_LOG=DEBUG when integrating new custom api_base endpoints.
- Verify custom gateways return OpenAI-spec bodies with a non-empty choices array before adopting them.
- Keep litellm updated; response-schema fixes land frequently.
When it happens
Trigger: Calling litellm.completion() on a text-completion model where the transformation layer receives a None response object (empty provider response body) or an uninitialized ModelResponse; typically after a 200 response whose body failed to deserialize into TextCompletionResponse.
Common situations: Custom api_base gateways returning empty 200 bodies; provider API changes altering response shape; mocking/streaming tests that pass None where a response object is expected; version mismatches between litellm and the openai SDK pydantic models.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Braintrust API error: {e.response.text}
- Failed to connect to Braintrust API: {str(e)}
- Error apply_db_fixes: {str(e)}
- Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
- No Braintrust API token provided. Pass via Authorization hea
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/a42feb5a69475a6e.
Report an issue: GitHub.