BerriAI/litellm · error · DashScopeError

Failed to parse DashScope response as JSON

Error message

Failed to parse DashScope response as JSON: {e}

What it means

LiteLLM's DashScope embedding handler calls raw_response.json() on the HTTP body returned by the embeddings endpoint (default https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings, overridable via api_base or DASHSCOPE_API_BASE) and the body was not valid JSON. The original parser exception is embedded in the message and the error is raised as DashScopeError carrying the upstream HTTP status code. Typical root cause: something other than the DashScope API answered (HTML gateway page, empty body, wrong host).

Solutions

  1. Inspect the embedded parser exception and, in a debug run, log raw_response.text for the same call — the non-JSON payload (usually HTML) tells you which server actually answered
  2. Verify DASHSCOPE_API_BASE / api_base points at the DashScope compatible-mode endpoint (e.g. https://dashscope.aliyuncs.com/compatible-mode/v1) and not a docs or console page
  3. If the body is a gateway/proxy 5xx page, retry with exponential backoff or fail over to another embedding provider
  4. Bypass or correctly configure corporate proxies (HTTPS_PROXY) so the API response reaches httpx untouched

Example fix

# before
os.environ['DASHSCOPE_API_BASE'] = 'https://help.aliyun.com/zh/model-studio'  # docs page -> HTML body
litellm.embedding(model='dashscope/text-embedding-v3', input=['hi'])

# after
os.environ['DASHSCOPE_API_BASE'] = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
litellm.embedding(model='dashscope/text-embedding-v3', input=['hi'])
Defensive patterns

Strategy: try-catch

Try / catch

try:
    resp = litellm.embedding(model='dashscope/text-embedding-v3', input=['hi'])
except Exception as e:
    status = getattr(e, 'status_code', None)
    if status is not None and status >= 500:
        backoff_and_retry()  # transient HTML 5xx page / outage
    else:
        log_raw_body_hint(e)  # message embeds the JSON parse exception
        raise

Prevention

When it happens

Trigger: litellm.embedding(model='dashscope/text-embedding-v3', input=[...]) when DASHSCOPE_API_BASE is mistyped and points at a console/docs URL, a corporate proxy/WAF returns an HTML block page, the connection drops mid-body leaving truncated JSON, or DashScope serves an HTML 5xx page during an outage.

Common situations: DASHSCOPE_API_BASE set to a help.aliyun.com or console page instead of the compatible-mode API; egress proxy injecting an auth page; regional outage returning HTML; response garbled by a middlebox so httpx cannot decode it.

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


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

Appendix: 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 77b7c6c40c)