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
- Verify api_base actually reaches LangFlow: curl -i {api_base}/api/v1/run/<flow_id> and inspect Content-Type
- Fix proxy/gateway issues (bypass the corporate proxy, correct the port, fix TLS) so LangFlow's JSON responses pass through
- 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
- Smoke-test the full URL (curl -i, check Content-Type: application/json) whenever api_base changes
- Exclude the LangFlow host from corporate proxies/VPNs that inject HTML portals
- Monitor for 5xx from gateways in front of LangFlow and alert on non-JSON content types
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
- Could not extract a message from the LangFlow response; ensu
- Failed to parse Braintrust API response: {str(e)}
- Error apply_db_fixes: {str(e)}
- Invalid content moderation response: {redacted_text}
- litellm_params is required for LangFlowA2AConfig (must conta
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/eece14736a06590a.
Report an issue: GitHub.