BerriAI/litellm · error · DashScopeError

Failed to parse DashScope response as JSON: {e}

Error message

Failed to parse DashScope response as JSON: {e}

What it means

After the DashScope embedding HTTP call succeeds at the transport level, litellm parses the body with response.json(); if the body is not valid JSON (e.g. an HTML error page from a gateway), it raises DashScopeError with status_code=raw_response.status_code and a message embedding the underlying JSON parse exception. It indicates the wrong shape of response, not necessarily an HTTP failure.

Source

Thrown at litellm/llms/dashscope/embed/transformation.py:133

            if value is not None:
                data[key] = value
        return data

    def transform_embedding_response(
        self,
        model: str,
        raw_response: httpx.Response,
        model_response: EmbeddingResponse,
        logging_obj: LiteLLMLoggingObj,
        api_key: str | None,
        request_data: dict,
        optional_params: dict,
        litellm_params: dict,
    ) -> EmbeddingResponse:
        try:
            response_json: Final = raw_response.json()
        except Exception as e:
            raise DashScopeError(
                status_code=raw_response.status_code,
                message=f"Failed to parse DashScope response as JSON: {e}",
            )

        logging_obj.post_call(
            input=request_data.get("input"),
            api_key=api_key,
            additional_args={"complete_input_dict": request_data},
            original_response=response_json,
        )

        if "error" in response_json:
            error: Final = response_json["error"]
            message: Final = error.get("message", str(error)) if isinstance(error, dict) else str(error)
            raise DashScopeError(
                status_code=raw_response.status_code,
                message=message,
            )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Log raw_response.text (first ~500 chars) to identify what the intermediary returned — the HTML title usually names the proxy/firewall
  2. Verify api_base is the real DashScope endpoint unless you intentionally use a gateway
  3. Whitelist/bypass the proxy for the DashScope domain, or fix the gateway to pass through JSON errors
  4. Retry with backoff for transient 502/504 gateway pages

Example fix

# before
resp = litellm.embedding(model="dashscope/text-embedding-v3", input=["hi"])
# DashScopeError: Failed to parse DashScope response as JSON: Expecting value...

# after (debug what the body actually is)
import httpx, os
r = httpx.post("https://dashscope-intl.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding",
              headers={"Authorization": f"Bearer {os.environ['DASHSCOPE_API_KEY']}"},
              json={"model": "text-embedding-v3", "input": {"texts": ["hi"]}})
print(r.status_code, r.headers.get("content-type"), r.text[:300])
Defensive patterns

Strategy: try-catch

Try / catch

try:
    vecs = litellm.embedding(model="dashscope/text-embedding-v3", input=texts)
except Exception as e:
    if "Failed to parse DashScope response as JSON" in str(e):
        logging.error("non-JSON response from DashScope — check api_base/proxy: %s", str(e)[:300])
        raise
    raise

Prevention

When it happens

Trigger: DashScope embeddings endpoint (or a custom api_base in front of it) returning non-JSON: HTML 502/504 pages from proxies, XML/WAF block pages, empty bodies, or text/plain gateway errors — commonly when api_base is misconfigured or an intermediary (corporate proxy, Cloudflare) intercepts the request.

Common situations: Custom api_base pointing at a proxy that returns HTML on failure; DashScope regional outage pages; rate-limiter/WAF returning non-JSON; response body truncated by a middlebox so JSON is malformed.

Understand the failure class

Related errors


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