gitbutlerapp/gitbutler · error

Anthropic API error ( )

Error message

Anthropic API error ({status}): {error_text}

What it means

This error is raised in message_raw when the Anthropic HTTP API returns a non-2xx status. The library bails with the HTTP status code and the full response body so the developer can see exactly what the API rejected (auth failure, bad model name, rate limit, malformed request, etc.). It wraps every possible server-side rejection into one anyhow error.

Solutions

  1. Read the error_text in the message — the Anthropic response body names the exact problem
  2. Verify the API key is set and valid
  3. Check the model name matches an Anthropic model identifier
  4. Inspect request size against the model's context limit; retry with backoff on 429/5xx

Example fix

// before: blind retry on any failure
let msg = provider.message(req).await?;
// after: inspect status first
match provider.message(req).await {
    Err(e) if e.to_string().contains("429") => retry_with_backoff(req).await,
    other => other,
}
Defensive patterns

Strategy: try-catch

Validate before calling

// TS/JS
if (!process.env.ANTHROPIC_API_KEY) throw new Error('ANTHROPIC_API_KEY not set');

Try / catch

// Rust
match provider.message(req).await {
    Err(e) => {
        let msg = e.to_string();
        if msg.contains("429") { /* backoff + retry */ }
        else if msg.contains("401") { /* fix API key */ }
        else { return Err(e); }
    }
    Ok(r) => r,
}

Prevention

When it happens

Trigger: Calling message, stream_response, or tool_calling_stream against the Anthropic API and receiving any non-success HTTP status (401 invalid API key, 400 bad request/model, 429 rate limit, 5xx server error).

Common situations: Expired or missing ANTHROPIC_API_KEY, wrong model identifier, oversized prompt exceeding context window, hitting rate limits, or Anthropic outages.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/44f5a4ca664bbeb0. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-llm/src/anthropic.rs:83

    async fn message(&self, request: &AnthropicRequest) -> Result<AnthropicResponse> {
        let response = self.message_raw(request).await?;
        let anthropic_response: AnthropicResponse = response.json().await?;
        Ok(anthropic_response)
    }

    async fn message_raw(&self, request: &AnthropicRequest) -> Result<Response> {
        let api_base = self.api_base();
        let response = self
            .client
            .post(format!("{api_base}/messages"))
            .json(request)
            .send()
            .await?;

        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await?;
            anyhow::bail!("Anthropic API error ({status}): {error_text}");
        }

        Ok(response)
    }

    fn api_base(&self) -> &str {
        match self.kind {
            CredentialsKind::GitButlerProxied => GB_ANTHROPIC_API_BASE,
            _ => ANTHROPIC_API_BASE,
        }
    }
}

#[derive(Debug, Clone)]
pub struct AnthropicProvider {
    model: Option<String>,
    credentials: (CredentialsKind, Sensitive<String>),
}

View on GitHub (pinned to 58e5313667)