Hmbown/CodeWhale · error · anyhow::Error

translate: HTTP

Error message

translate: HTTP {status}: {error_text}

What it means

The translation HTTP call to the provider returned a non-success status; the client reads a bounded amount of the error body, sanitizes it, and surfaces it as `translate: HTTP {status}: {error_text}`. This is a generic wrapper around any provider-side HTTP error (4xx/5xx) during translation.

Solutions

  1. Read the status and sanitized error_text: 401/403 → fix the API key; 429 → retry with backoff; 400 → fix model name/payload; 5xx → wait and retry.
  2. Verify the provider API key is set and valid for the translation endpoint.
  3. Check the model name configured for translation exists on that provider.
  4. If 5xx persists, check provider status page and retry later.
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: verify key present and non-empty
fn ensure_key(env: &str) -> Result<(), String> {
    std::env::var(env).ok().filter(|k| !k.trim().is_empty()).ok_or_else(|| format!("{env} not set"))
}

Try / catch

match result {
    Err(e) if e.to_string().starts_with("translate: HTTP ") => {
        if e.to_string().contains(" 429 ") { backoff_retry().await?; }
        else if e.to_string().contains(" 401 ") { eprintln!("check translation provider API key"); }
        else { return Err(e); }
    }
    r => r?,
}

Prevention

When it happens

Trigger: Provider returns 401/403 (bad or missing API key), 429 (rate limit), 400 (bad request/model name), or 5xx (provider outage) on the translation endpoint.

Common situations: Expired or wrong API key for the translation provider; exceeding rate limits; wrong model name in translation config; provider regional outage.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/2e9624c9823e9ab2. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/client.rs:2867

        chat::apply_route_reasoning_controls(
            &mut body,
            self.api_provider,
            &self.base_url,
            &model,
            Some("off"),
        );

        self.apply_provider_routing(&mut body);
        let response = self.send_json_with_retry(&url, &body).await?;
        let status = response.status();
        if !status.is_success() {
            let raw_error_text = bounded_error_text(response, ERROR_BODY_MAX_BYTES).await;
            let error_text = sanitize_http_error_body(
                Some(self.api_provider.display_name()),
                status.as_u16(),
                &raw_error_text,
            );
            anyhow::bail!("translate: HTTP {status}: {error_text}");
        }

        let value: serde_json::Value = response.json().await?;
        let usage_reported = value
            .get("usage")
            .and_then(Value::as_object)
            .is_some_and(|usage| {
                [
                    "input_tokens",
                    "prompt_tokens",
                    "output_tokens",
                    "completion_tokens",
                    "total_tokens",
                ]
                .iter()
                .any(|field| usage.contains_key(*field))
            });
        let usage = parse_usage(value.get("usage"));

View on GitHub (pinned to 73e0f67d83)