Fosowl/agenticSeek · error · Exception
Anthropic API error: {str(e)}
Error message
Anthropic API error: {str(e)} What it means
This is the catch-all wrapper in anthropic_fn (sources/llm_provider.py:281): any exception in the try block — SDK errors such as 401 authentication_error, 429 rate_limit_error, 400 invalid_request_error, 5xx overloaded_error, the library's own 'Anthropic response is empty.' check, or a TypeError from response.content[0] — is re-raised as Exception(f"Anthropic API error: {str(e)}") with the original attached as __cause__.
Source
Thrown at sources/llm_provider.py:281
system_message = message['content']
else:
messages.append(clean_message)
try:
response = client.messages.create(
model=self.model,
max_tokens=1024,
messages=messages,
system=system_message
)
if response is None:
raise Exception("Anthropic response is empty.")
thought = response.content[0].text
if verbose:
print(thought)
return thought
except Exception as e:
raise Exception(f"Anthropic API error: {str(e)}") from e
def google_fn(self, history, verbose=False):
"""
Use google gemini to generate text.
"""
base_url = self.server_ip
if self.is_local:
raise Exception("Google Gemini is not available for local use. Change config.ini")
client = OpenAI(api_key=self.api_key, base_url="https://generativelanguage.googleapis.com/v1beta/openai/")
try:
response = client.chat.completions.create(
model=self.model,
messages=history,
)
if response is None:
raise Exception("Google response is empty.")
thought = response.choices[0].message.contentView on GitHub (pinned to ae57a23577)
Solutions
- Read the wrapped str(e): 401 → fix the API key, 400 → fix the request payload, 429 → back off and retry, 529/5xx → retry later.
- Verify ANTHROPIC_API_KEY (self.api_key) is set, active, and has available credit.
- Ensure history contains at least one non-system user/assistant message — the code extracts system messages into system_message and an all-system history yields an empty messages array that the API rejects.
- Use a valid Anthropic model name (claude-* family), not an OpenAI model identifier.
- Retry 429/overloaded errors with exponential backoff.
- Log e.__cause__ to see the original anthropic SDK exception with request IDs for support/debugging.
Example fix
// before: history = [{"role": "system", "content": "You are helpful"}]
// after: include at least one user message
history = [
{"role": "system", "content": "You are helpful"},
{"role": "user", "content": "Hello!"}
] Defensive patterns
Strategy: try-catch
Validate before calling
import os, httpx
def assert_anthropic_ready(api_key=None, model="claude-sonnet-4-20250514"):
key = api_key or os.environ.get("ANTHROPIC_API_KEY")
if not key:
raise RuntimeError("ANTHROPIC_API_KEY is not set")
r = httpx.post(
"https://api.anthropic.com/v1/messages",
headers={"x-api-key": key, "anthropic-version": "2023-06-01"},
json={"model": model, "max_tokens": 1, "messages": [{"role": "user", "content": "hi"}]},
timeout=10,
)
if r.status_code == 401:
raise RuntimeError("Anthropic API key is invalid")
if r.status_code == 404:
raise RuntimeError(f"Model '{model}' not found; use a claude-* model id")
r.raise_for_status() Type guard
def is_retryable_anthropic_error(err: BaseException) -> bool:
"""Transient errors worth retrying vs permanent request problems."""
msg = str(err).lower()
return any(tok in msg for tok in ("429", "rate limit", "overloaded", "529", "503", "timeout")) Try / catch
import time
def anthropic_fn_with_retry(provider, history, retries=4):
for attempt in range(retries):
try:
return provider.anthropic_fn(history)
except Exception as e:
if is_retryable_anthropic_error(e) and attempt < retries - 1:
time.sleep(2 ** attempt)
continue
if "401" in str(e) or "authentication" in str(e).lower():
raise RuntimeError("Fix ANTHROPIC_API_KEY (invalid/expired).") from e.__cause__
if "400" in str(e) or "invalid_request" in str(e).lower():
raise RuntimeError(
"Bad request: ensure history has at least one non-system "
"message and a valid claude-* model name."
) from e.__cause__
raise Prevention
- Set and verify ANTHROPIC_API_KEY at startup; never hard-code it in source.
- Always include at least one user/assistant message in history — system-only histories become an empty messages array and fail with 400.
- Use valid Anthropic model ids (claude-*) rather than OpenAI-style names.
- Retry 429/overloaded responses with exponential backoff instead of failing the whole run.
- Log e.__cause__ (the anthropic SDK exception) to capture error codes and request IDs for debugging.
When it happens
Trigger: Any failure during client.messages.create(model=self.model, max_tokens=1024, messages=messages, system=system_message): invalid API key, model name typo, empty/invalid messages list (e.g. history containing only a system message, which is stripped into system_message leaving messages empty), max_tokens/param issues, rate limits, or empty-response/None-content access failures.
Common situations: ANTHROPIC_API_KEY missing/expired/incorrect in config or env; using an OpenAI-style model name ('gpt-4') with the Anthropic provider; history made up solely of system-role messages so the required messages array is empty (400 invalid_request_error); hitting 429 rate limits during bursts; max_tokens smaller than the model minimum; SDK version incompatible with the current API.
Related errors
- OpenAI API error: {str(e)}
- LiteLLM API error: {str(e)}
- Provider {self.provider_name} failed: {str(e)}
- Anthropic response is empty.
- GOOGLE API error: {str(e)}
AI-assisted analysis of Fosowl/agenticSeek@ae57a23577 (2026-08-30).
Data as JSON: /api/errors/bb765b9bda836306.
Report an issue: GitHub.