BerriAI/litellm · error · LangGraphError

{response.aread()}

Error message

{response.aread()}

What it means

Async twin of the sync streaming guard: get_async_custom_stream_wrapper POSTs to {api_base}/runs/stream via await client.post(...), and any non-200 response raises LangGraphError with that status code and the raw body (str(await response.aread())). The body is the LangGraph server's own error text.

Source

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

        )
        from litellm.utils import CustomStreamWrapper

        if client is None or not isinstance(client, AsyncHTTPHandler):
            client = get_async_httpx_client(llm_provider=cast(Any, "langgraph"), params={})

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

        # Make async streaming request
        response: Final = await 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(await response.aread()))

        # 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 77b7c6c40c)

Solutions

  1. Read e.status_code and e.message to get the server's own error detail
  2. Fix credentials for 401/403 (pass api_key so it is sent as Authorization: Bearer)
  3. Fix api_base for 404 (must be the API root; /runs/stream is appended)
  4. Validate the assistant/graph id in the model name for 422
  5. Retry transient 5xx with backoff; verify with a direct httpx POST

Example fix

# before
stream = await litellm.acompletion(model="langgraph/agent", stream=True, messages=[...])  # LangGraphError

# after
try:
    stream = await litellm.acompletion(
        model="langgraph/agent", api_base=LANGGRAPH_URL, api_key=LANGGRAPH_KEY, stream=True, messages=[...]
    )
except Exception as e:
    status = getattr(e, "status_code", None)
    if status in (429, 500, 502, 503):
        await asyncio.sleep(2)
        stream = await litellm.acompletion(model="langgraph/agent", stream=True, messages=[...])
    else:
        raise
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx

async def langgraph_ok(base: str, api_key: str | None) -> bool:
    try:
        r = await httpx.AsyncClient().post(
            f"{base.rstrip('/')}/runs/wait",
            headers={"Authorization": f"Bearer {api_key}"} if api_key else {},
            json={"assistant_id": "agent", "input": {"messages": []}},
            timeout=10,
        )
        return r.status_code < 400
    except httpx.HTTPError:
        return False

Try / catch

try:
    stream = await litellm.acompletion(model="langgraph/agent", stream=True, messages=msgs, api_base=base)
except Exception as e:
    status = getattr(e, "status_code", None)
    if status in (429, 500, 502, 503) and attempt < MAX_RETRIES:
        await asyncio.sleep(2 ** attempt)
        continue
    log.error("LangGraph async stream failed: %s %s", status, getattr(e, "message", e))
    raise

Prevention

When it happens

Trigger: await litellm.acompletion(model="langgraph/...", stream=True, ...) where the server responds non-200: 404 wrong api_base, 401/403 bad or missing Bearer key, 422 invalid payload or unknown graph/assistant, 5xx server failure.

Common situations: Async FastAPI service calling a LangGraph deployment with a rotated/expired token; wrong base URL in an async worker's env; graph name typo in the model string.

Related errors


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