{"record":{"id":"963fa1854aea48b9","repo":"Hmbown/CodeWhale","slug":"codewhale-account-request-failed-http-code-c","errorCode":null,"errorMessage":"Codewhale account request failed (HTTP {}, code {code})","messagePattern":"Codewhale account request failed \\(HTTP (.+?), code (.+?)\\)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/cloud.rs","lineNumber":1025,"sourceCode":"fn parse_json_body<T: DeserializeOwned>(body: &[u8]) -> Result<T> {\n    serde_json::from_slice(body).context(\"The Codewhale service returned an invalid JSON response\")\n}\n\nfn response_error(response: &CloudResponse) -> anyhow::Error {\n    let code = serde_json::from_slice::<serde_json::Value>(&response.body)\n        .ok()\n        .and_then(|body| {\n            body.get(\"code\")\n                .and_then(serde_json::Value::as_str)\n                .or_else(|| {\n                    body.get(\"error\")\n                        .and_then(|error| error.get(\"code\"))\n                        .and_then(serde_json::Value::as_str)\n                })\n                .and_then(safe_error_code)\n        });\n    match code {\n        Some(code) => anyhow!(\n            \"Codewhale account request failed (HTTP {}, code {code})\",\n            response.status\n        ),\n        None => anyhow!(\n            \"Codewhale account request failed (HTTP {})\",\n            response.status\n        ),\n    }\n}\n\nfn safe_error_code(code: &str) -> Option<String> {\n    if code.is_empty()\n        || code.len() > 80\n        || !code\n            .bytes()\n            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-' | b'.'))\n    {\n        return None;","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/cli/src/cloud.rs#L1007-L1043","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-authenticate (`codewhale cloud login`) if the code indicates auth failure","Look up the reported code in the Codewhale account API error catalogue for the specific remedy","Back off and retry for rate-limit (429) codes","Verify system clock skew if signatures/auth codes are rejected"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..5 {\n    match client.account_request(&req).await {\n        Ok(resp) => return Ok(resp),\n        Err(err) if err.to_string().contains(\"HTTP 429\") || err.to_string().contains(\"HTTP 5\") => {\n            tokio::time::sleep(backoff(attempt)).await; // exponential backoff\n        }\n        Err(err) if err.to_string().contains(\"HTTP 401\") => {\n            client.reauthenticate().await?; // refresh credentials, then retry once\n        }\n        Err(err) => return Err(err),\n    }\n}","preventionTips":["Refresh tokens before expiry instead of waiting for 401 codes","Respect rate limits: batch key operations rather than hammering the account API","Map documented error codes to user-facing remedies in your wrapper"],"tags":["cli","cloud","http","api-error","rust"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}