BerriAI/litellm · error · DatabricksException
Unable to get json response
Error message
Unable to get json response - {e}, Original Response: {raw_response.text} What it means
The Databricks chat completion handler wraps both raw_response.json() and construction of the DatabricksResponse pydantic model in one try/except. Any failure — a non-JSON body, or JSON missing required completion fields (id/created/usage) — raises DatabricksException 'Unable to get json response' embedding the parser error plus the entire original response text (request logging already ran with a redacted api_key). The 'Original Response' portion is your diagnosis.
Solutions
- Read 'Original Response' in the message — it shows exactly what came back (login HTML, error JSON, empty string)
- Verify the endpoint directly: curl <api_base>/<endpoint>/invocations with the same token
- Fix DATABRICKS_API_BASE so it targets the serving-endpoints API path, not the workspace UI
- If the body is valid JSON but lacks id/created/usage, the endpoint is not returning an OpenAI-compatible schema — use an OpenAI-compatible serving config or the right provider prefix
Defensive patterns
Strategy: try-catch
Validate before calling
import os
def databricks_base_ok() -> bool:
base = os.getenv('DATABRICKS_API_BASE', '')
return base.rstrip('/').endswith('/serving-endpoints') # not the workspace UI
if not databricks_base_ok():
raise RuntimeError('DATABRICKS_API_BASE must target the serving-endpoints API path') Try / catch
try:
resp = litellm.completion(model='databricks/my-ep', messages=msgs)
except Exception as e:
if 'Unable to get json response' in str(e):
log.error('non-OpenAI body from endpoint: %s', str(e)[-2000:]) # contains Original Response
raise Prevention
- Verify the serving endpoint with one curl invocation during deployment
- Ensure the endpoint is deployed and OpenAI-compatible before wiring it into litellm
When it happens
Trigger: litellm.completion(model='databricks/...', ...) where the serving endpoint returns HTML (workspace login redirect when the URL points at the UI), an error JSON without completion fields, a 200 from a non-OpenAI-compatible gateway schema, or a truncated body from a dropped connection.
Common situations: DATABRICKS_API_BASE pointing at the workspace UI instead of the serving-endpoints path; endpoint in 'building/failed' state returning an error body; external-model endpoints with non-OpenAI response shapes; response-size limits at a proxy.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- AgentCore: Failed to read/parse JSON response body
- Cisco AI Defense API returned a non-JSON response
- Error parsing BFL response
- Error parsing BFL response
- Error parsing initial response
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/3e15d4c1751ece37.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/llms/databricks/chat/transformation.py:626
json_mode: bool | None = None,
) -> ModelResponse:
# Redact sensitive data before logging to prevent credential leakage
redacted_request_data: Final = self.redact_sensitive_data(request_data)
## LOGGING - Never log actual API keys
logging_obj.post_call(
input=messages,
api_key="[REDACTED]",
original_response=raw_response.text,
additional_args={"complete_input_dict": redacted_request_data},
)
## RESPONSE OBJECT
try:
completion_response: Final = DatabricksResponse(**raw_response.json())
except Exception as e:
response_headers: Final = getattr(raw_response, "headers", None)
raise DatabricksException(
message=f"Unable to get json response - {e}, Original Response: {raw_response.text}",
status_code=raw_response.status_code,
headers=response_headers,
)
_custom_llm_provider: Final = litellm_params.get("custom_llm_provider") or "databricks"
_response_model: Final = completion_response.get("model") or ""
model_response.model = f"{_custom_llm_provider}/{_response_model}"
model_response.id = completion_response["id"]
model_response.created = completion_response["created"]
setattr(model_response, "usage", Usage(**completion_response["usage"]))
model_response.choices = self._transform_dbrx_choices(
choices=completion_response["choices"],
json_mode=json_mode,
)
return model_responseView on GitHub (pinned to 77b7c6c40c)