Hmbown/CodeWhale · error

Codewhale account request failed (HTTP {}, code {code})

Error message

Codewhale account request failed (HTTP {}, code {code})

What it means

Generic failure error for any non-2xx response from the Codewhale account API. The response body's machine-readable code (top-level "code", or "error.code") is included only after safe_error_code sanitizes it (non-empty, <=80 chars, ASCII alphanumeric plus _ - .), so hostile or oversized text never reaches the error message. This variant means the body carried a recognized code.

Source

Thrown at crates/cli/src/cloud.rs:1025

fn parse_json_body<T: DeserializeOwned>(body: &[u8]) -> Result<T> {
    serde_json::from_slice(body).context("The Codewhale service returned an invalid JSON response")
}

fn response_error(response: &CloudResponse) -> anyhow::Error {
    let code = serde_json::from_slice::<serde_json::Value>(&response.body)
        .ok()
        .and_then(|body| {
            body.get("code")
                .and_then(serde_json::Value::as_str)
                .or_else(|| {
                    body.get("error")
                        .and_then(|error| error.get("code"))
                        .and_then(serde_json::Value::as_str)
                })
                .and_then(safe_error_code)
        });
    match code {
        Some(code) => anyhow!(
            "Codewhale account request failed (HTTP {}, code {code})",
            response.status
        ),
        None => anyhow!(
            "Codewhale account request failed (HTTP {})",
            response.status
        ),
    }
}

fn safe_error_code(code: &str) -> Option<String> {
    if code.is_empty()
        || code.len() > 80
        || !code
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-' | b'.'))
    {
        return None;

View on GitHub (pinned to 8880682c63)

Solutions

  1. Re-authenticate (`codewhale cloud login`) if the code indicates auth failure
  2. Look up the reported code in the Codewhale account API error catalogue for the specific remedy
  3. Back off and retry for rate-limit (429) codes
  4. Verify system clock skew if signatures/auth codes are rejected
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..5 {
    match client.account_request(&req).await {
        Ok(resp) => return Ok(resp),
        Err(err) if err.to_string().contains("HTTP 429") || err.to_string().contains("HTTP 5") => {
            tokio::time::sleep(backoff(attempt)).await; // exponential backoff
        }
        Err(err) if err.to_string().contains("HTTP 401") => {
            client.reauthenticate().await?; // refresh credentials, then retry once
        }
        Err(err) => return Err(err),
    }
}

Prevention

When it happens

Trigger: Any account API call failing with a structured error body: 401 invalid/expired credentials, 400 bad request, 403 forbidden, 429 rate limited — where the JSON body includes a code field.

Common situations: OAuth token expired or cloud key revoked; rate limiting during scripted key operations; maintenance windows returning structured errors; wrong api_base hitting an endpoint with different semantics.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/963fa1854aea48b9. Report an issue: GitHub.