BerriAI/litellm · error · LangGraphError

str(response.read())

Error message

str(response.read())

What it means

For synchronous streaming requests to the LangGraph /runs/stream endpoint, any non-200 status from the server is converted into LangGraphError carrying the upstream status code and the raw response body (response.read()) as the message. The message is literally the response bytes stringified — it exists to surface the server's error detail (e.g. 404 unknown assistant, 401 bad key, 422 validation) to the caller.

Source

Thrown at litellm/llms/langgraph/chat/transformation.py:312

        )
        from litellm.utils import CustomStreamWrapper

        if client is None or not isinstance(client, HTTPHandler):
            client = _get_httpx_client(params={})

        verbose_logger.debug("Making sync streaming request to: %s", api_base)

        # Make streaming request
        response: Final = client.post(
            api_base,
            headers=headers,
            data=json.dumps(data),
            stream=True,
            logging_obj=logging_obj,
        )

        if response.status_code != 200:
            raise LangGraphError(status_code=response.status_code, message=str(response.read()))

        # Create iterator for SSE stream
        completion_stream: Final = self.get_streaming_response(model=model, raw_response=response)

        streaming_response: Final = CustomStreamWrapper(
            completion_stream=completion_stream,
            model=model,
            custom_llm_provider=custom_llm_provider,
            logging_obj=logging_obj,
        )

        # LOGGING
        logging_obj.post_call(
            input=messages,
            api_key="",
            original_response="first stream response received",
            additional_args={"complete_input_dict": data},
        )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the error message body: it contains the LangGraph server's own error JSON explaining the failure
  2. 404: verify the graph/assistant name in model="langgraph/<name>" against the deployment
  3. 401/403: check the LANGGRAPH_API_KEY / api_key value
  4. 422: align the input payload (messages/format) with the graph's current input schema
  5. 5xx: retry after the deployment is healthy
Defensive patterns

Strategy: try-catch

Validate before calling

def langgraph_stream_ready(api_base: str, api_key: str) -> bool:
    import requests
    r = requests.post(
        f"{api_base.rstrip('/')}/runs/stream",
        headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
        json={"assistant_id": "agent", "input": {"messages": []}, "stream_mode": "messages"},
        timeout=10,
    )
    return r.status_code == 200

Try / catch

from litellm.llms.langgraph.chat.transformation import LangGraphError

for attempt in range(3):
    try:
        stream = litellm.completion(model="langgraph/agent", messages=msgs, stream=True)
        for chunk in stream:
            ...
        break
    except LangGraphError as e:
        if e.status_code in (401, 403, 404, 422):
            raise  # config error — fix key/name/payload, do not retry
        if e.status_code >= 500 and attempt < 2:
            continue  # transient — retry
        raise

Prevention

When it happens

Trigger: Streaming (stream=True) against a LangGraph server when the assistant/graph name is wrong (404), the api_key is invalid (401/403), the payload fails validation (422), or the deployment is restarting (503).

Common situations: Model name not matching a deployed graph; expired or wrong-scoped LangGraph API key; schema mismatch after updating the graph's input schema; server temporarily unavailable during deploys.

Related errors


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