Hmbown/CodeWhale · error · MachineError

The Codewhale service returned HTTP

Error message

The Codewhale service returned HTTP {status}.

What it means

The api-keys Create command POSTs to /api/account/api-keys with Retry::Never. If the HTTP status is outside 2xx, the response is classified into a MachineError and returned as an anyhow error worded "The Codewhale service returned HTTP {status}." The key is not created locally.

Solutions

  1. Re-authenticate the Codewhale session if the status is 401
  2. Check account permissions/scopes for api-key creation on 403
  3. Fix the create arguments (expires_in_days, scopes) on 400/422
  4. Retry on 5xx; the create call is deliberately never auto-retried
  5. Run whoami to confirm the session is valid before creating keys

Example fix

# confirm the session first, then create
# before
codewhale account api-keys create --use-locally

# after
codewhale account api-keys whoami && codewhale account api-keys create --use-locally
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the session before creating keys
let who = client.whoami(&mut sleeper)?;

Try / catch

match create_key(&client, &body, &mut sleeper) {
    Ok(created) => store(created),
    Err(err) if err.to_string().contains("returned HTTP 401") => {
        eprintln!("Session expired; run `codewhale login` and retry");
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Running codewhale account api-keys create when the session credential is missing/expired (401), the account lacks permission (403), the request body is rejected (400/422), or the server errors (5xx).

Common situations: Expired Codewhale session cookie; creating keys on an account without the api-key scope; server-side validation rejecting expires_in_days or scopes; transient 502/503 from the service.

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@433685b202 (2026-09-15). Data as JSON: /api/errors/bce78a28de9b9792. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/cloud/machine.rs:916

            let body = serde_json::to_vec(&ApiKeyCreateRequest {
                name,
                expires_in_days: create.expires_in_days,
                scopes,
            })
            .context("failed to encode the Codewhale API key request")?;
            // `Retry::Never` is the whole point of the enum here: a POST that
            // actually succeeded server-side would mint a second key whose
            // one-time secret the caller never saw, and therefore can never
            // revoke by id from the output they hold.
            let response = client.execute_authenticated_with_retry(
                HttpMethod::Post,
                "/api/account/api-keys",
                Some(body),
                Retry::Never,
                sleeper,
            )?;
            if !(200..300).contains(&response.status) {
                return Err(anyhow::Error::new(classify(&response)));
            }
            let created: ApiKeyCreateResponse = decode_json(response)?;
            write_created_key(out, &created)?;
            if create.use_locally {
                save_key_as_local_codewhale_credential(provider_secrets, &created.secret, out)?;
            }
            Ok(())
        }
        ApiKeysCommand::List => {
            let response = client.execute_authenticated_with_retry(
                HttpMethod::Get,
                "/api/account/api-keys",
                None,
                Retry::Idempotent,
                sleeper,
            )?;
            if !(200..300).contains(&response.status) {
                return Err(anyhow::Error::new(classify(&response)));

View on GitHub (pinned to 433685b202)