HKUDS/DeepTutor · error · LLMAPIError
Anthropic stream error: {error_text}
Error message
Anthropic stream error: {error_text} What it means
The initial status check of _anthropic_stream: the POST for the SSE stream returned non-200, so the body is read and wrapped in LLMAPIError with the status and provider before any lines are iterated. The embedded error_text is Anthropic's own error JSON, so the message pinpoints the server-side reason.
Source
Thrown at deeptutor/services/llm/cloud_provider.py:785
temperature_value = temperature if temperature is not None else 0.7
data: dict[str, object] = {
"model": model,
"system": system_content,
"messages": msg_list,
"max_tokens": max_tokens_value,
"temperature": temperature_value,
"stream": True,
}
timeout = aiohttp.ClientTimeout(total=300)
connector = _get_aiohttp_connector()
async with aiohttp.ClientSession(
timeout=timeout, connector=connector, trust_env=True
) as session:
async with session.post(url, headers=headers, json=data) as response:
if response.status != 200:
error_text = await response.text()
raise LLMAPIError(
f"Anthropic stream error: {error_text}",
status_code=response.status,
provider="anthropic",
)
async for line in response.content:
line_str = line.decode("utf-8").strip()
if not line_str or not line_str.startswith("data:"):
continue
data_str = line_str[5:].strip()
if not data_str:
continue
try:
chunk_data = cast(dict[str, object], json.loads(data_str))
event_type = chunk_data.get("type")
if event_type == "content_block_delta":View on GitHub (pinned to 3e82f13042)
Solutions
- Decode e.status_code + error_text to find the exact cause (auth vs model vs limit).
- 429/529 → back off and retry, or rotate keys via KeyPool.
- 401 → refresh the API key in the profile.
- 404 → verify the model identifier exists for the account.
Example fix
// before
async for chunk in stream(prompt=p, binding="anthropic", model="claude-3", api_key=k):
...
# after
async for chunk in stream(prompt=p, binding="anthropic", model="claude-sonnet-4", api_key=k):
... Defensive patterns
Strategy: retry
Try / catch
try:
async for chunk in stream(prompt=p, binding="anthropic", model=m, api_key=k):
...
except LLMAPIError as e:
if e.status_code in (429, 529):
await asyncio.sleep(30) # then retry
elif e.status_code == 401:
raise RuntimeError("invalid Anthropic key") from e
else:
raise Prevention
- Use KeyPool rotation plus backoff for bursty Claude workloads.
- Verify model identifiers exist for your account before streaming.
- Degrade gracefully to non-streaming when gateways reject SSE.
When it happens
Trigger: Starting a Claude stream with an invalid key (401), unavailable model (404), rate limit (429), or overloaded service (529); proxy gateways rejecting stream:true.
Common situations: Rate-limited Claude accounts during bursts; model name typos; region-blocked endpoints routed via proxy; long-running apps holding stale keys past rotation.
Related errors
- Anthropic API error: {error_text}
- OpenAI stream error: {error_text}
- Cohere API error: {error_text}
- OpenAI API error: {error_text}
- Anthropic API key is missing from the active LLM profile.
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/b7c118c542955e4c.
Report an issue: GitHub.