BerriAI/litellm · error · LangFlowError

LangFlow returned a non-JSON response: {e}

Error message

LangFlow returned a non-JSON response: {e}

What it means

After the HTTP call to {api_base}/api/v1/run/{flow_id} returns, LiteLLM calls raw_response.json(); if the body is not valid JSON it raises LangFlowError with the upstream HTTP status code and the JSON parse exception text. Typical cause: the server returned HTML (auth portal, proxy error page, 502 gateway page) or plain text instead of the expected JSON.

Source

Thrown at litellm/llms/langflow/chat/transformation.py:233

    def transform_response(
        self,
        model: str,
        raw_response: httpx.Response,
        model_response: ModelResponse,
        logging_obj: LiteLLMLoggingObj,
        request_data: dict,
        messages: list[AllMessageValues],
        optional_params: dict,
        litellm_params: dict,
        encoding: Any,
        api_key: str | None = None,
        json_mode: bool | None = None,
    ) -> ModelResponse:
        try:
            response_json: Final = raw_response.json()
        except Exception as e:
            raise LangFlowError(
                message=f"LangFlow returned a non-JSON response: {e}",
                status_code=raw_response.status_code,
            )

        verbose_logger.debug("LangFlow response: %s", response_json)

        content: Final = self._extract_content_from_response(response_json)
        if content is None:
            raise LangFlowError(
                message=(
                    "Could not extract a message from the LangFlow response; "
                    "ensure the flow ends in a Chat Output component"
                ),
                status_code=500,
            )

        message: Final = Message(content=content, role="assistant")
        choice: Final = Choices(finish_reason="stop", index=0, message=message)

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Verify api_base actually reaches LangFlow: curl -i {api_base}/api/v1/run/<flow_id> and inspect Content-Type
  2. Fix proxy/gateway issues (bypass the corporate proxy, correct the port, fix TLS) so LangFlow's JSON responses pass through
  3. If an auth portal responds, supply the correct LangFlow api_key or whitelist the client
Defensive patterns

Strategy: retry

Validate before calling

def langflow_endpoint_ok(api_base: str, api_key: str | None) -> bool:
    import requests
    r = requests.get(f"{api_base.rstrip('/')}/api/v1/flows", headers={"Authorization": f"Bearer {api_key or ''}"}, timeout=5)
    ct = r.headers.get("content-type", "")
    return r.status_code < 500 and "json" in ct

Try / catch

try:
    resp = litellm.completion(model="langflow/x", messages=msgs)
except LangFlowError as e:
    if "non-JSON response" in str(e):
        # upstream/proxy returned HTML or errored: check api_base reachability, then retry with backoff
        if langflow_endpoint_ok(base, key):
            retry_with_backoff(...)
        else:
            alert_ops(f"LangFlow at {base} not returning JSON (status {e.status_code})")

Prevention

When it happens

Trigger: api_base points at a reverse proxy / SSO portal that returns an HTML login page; a 502/503 from a gateway in front of LangFlow; hitting a non-LangFlow server (wrong port) that answers in text; a truncated body from a timeout mid-transfer.

Common situations: Wrong LANGFLOW_API_BASE (e.g. pointing at the frontend port of a different service); corporate proxy intercepting the request; LangFlow behind a load balancer that errors; TLS misconfiguration returning an error page.

Related errors


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