Hmbown/CodeWhale · error

Codewhale account request failed

Error message

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

What it means

Generic handler for failed HTTP responses from the Codewhale account API. When the response body carries a machine-readable `code` field (passed through `safe_error_code`), the error includes both the HTTP status and that code so the developer can identify the exact API-side failure.

Solutions

  1. Read the `code` in the message and map it to the documented account API error.
  2. Re-authenticate: `codewhale login` or set MACHINE_KEY_ENV with a fresh key (`codewhale account api-keys create`).
  3. Retry later if the status is 5xx; check the Codewhale service status for outages.
Defensive patterns

Strategy: try-catch

Try / catch

match result {
    Err(e) if e.to_string().contains("code invalid_api_key") => reauthenticate(),
    Err(e) => log::error("account request failed: {e}"),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Any account API request (login, key management, provider config) that returns a non-success status with a JSON error body containing a `code` string.

Common situations: 401 with `invalid_api_key`, 403 with `forbidden`, 404 with `not_found`, 409 with a conflict code from the account service; expired or revoked API keys.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/8d91d24b94b4f974. Report an issue: GitHub.

Appendix: source

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

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 73e0f67d83)