BerriAI/litellm · error · OpenAIError

Unable to get json response - {e}, Original Response: {raw_r

Error message

Unable to get json response - {e}, Original Response: {raw_response.text}

What it means

In the OpenAI chat transformation, `raw_response.json()` failure raises OpenAIError with the parse exception, the original response text, the status code, and the response headers. It means the OpenAI-compatible endpoint returned a non-JSON body.

Source

Thrown at litellm/llms/openai/chat/gpt_transformation.py:620

        Returns:
            dict: The transformed response.
        """

        ## LOGGING
        logging_obj.post_call(
            input=messages,
            api_key=api_key,
            original_response=raw_response.text,
            additional_args={"complete_input_dict": request_data},
        )

        ## RESPONSE OBJECT
        try:
            completion_response: Final = raw_response.json()
        except Exception as e:
            response_headers: Final = getattr(raw_response, "headers", None)
            raise OpenAIError(
                message=f"Unable to get json response - {e}, Original Response: {raw_response.text}",
                status_code=raw_response.status_code,
                headers=response_headers,
            )
        raw_response_headers: Final = dict(raw_response.headers)
        final_response_obj: Final = convert_to_model_response_object(
            response_object=completion_response,
            model_response_object=model_response,
            hidden_params={"headers": raw_response_headers},
            _response_headers=raw_response_headers,
        )

        return cast(ModelResponse, final_response_obj)

    def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:
        return OpenAIError(
            status_code=status_code,
            message=error_message,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Check the 'Original Response' in the message — it shows exactly what body came back (often an HTML page revealing the real problem).
  2. Fix api_base to point at the correct API root (usually must include /v1, e.g. http://host:8000/v1).
  3. Bypass or configure proxies/SSL inspection that inject HTML responses.
  4. Verify the server is actually an OpenAI-compatible API with curl /v1/models.

Example fix

# before
litellm.completion(model="openai/m", api_base="http://localhost:8000")  # missing /v1

# after
litellm.completion(model="openai/m", api_base="http://localhost:8000/v1")
Defensive patterns

Strategy: validation

Validate before calling

import httpx
r = httpx.get(f"{api_base}/models", headers={"Authorization": f"Bearer {api_key}"})
if "json" not in r.headers.get("content-type", ""):
    raise ValueError(f"{api_base} is not returning JSON — check URL/proxy: {r.text[:200]}")

Try / catch

try:
    resp = litellm.completion(model="openai/m", messages=msgs, api_base=base)
except litellm.exceptions.OpenAIError as e:
    if "Unable to get json response" in str(e):
        # body was not JSON: message embeds the original text
        diagnose_non_json_body(str(e))

Prevention

When it happens

Trigger: Any OpenAI-path completion where the server returns HTML or plain text: Cloudflare challenge pages, gateway 502 HTML, empty bodies, gzip corruption, or plain-text error strings from misconfigured OpenAI-compatible servers.

Common situations: Self-hosted OpenAI-compatible endpoints (vLLM, LocalAI, LM Studio) behind proxies; api_base typos hitting a website instead of an API; corporate SSL inspection returning an HTML block page; or a base URL missing the /v1 path so the server returns an HTML 404.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/0e7f0a0ccbf264b7. Report an issue: GitHub.