{"record":{"id":"c389da02071e0bea","repo":"Hmbown/CodeWhale","slug":"the-codewhale-service-returned-http-status-server-message","errorCode":null,"errorMessage":"The Codewhale service returned HTTP {status}: {server_message}","messagePattern":"The Codewhale service returned HTTP (.+?): (.+?)","errorType":"http","errorClass":"MachineError","httpStatus":null,"severity":"error","filePath":"crates/cli/src/cloud/machine.rs","lineNumber":916,"sourceCode":"            let body = serde_json::to_vec(&ApiKeyCreateRequest {\n                name,\n                expires_in_days: create.expires_in_days,\n                scopes,\n            })\n            .context(\"failed to encode the Codewhale API key request\")?;\n            // `Retry::Never` is the whole point of the enum here: a POST that\n            // actually succeeded server-side would mint a second key whose\n            // one-time secret the caller never saw, and therefore can never\n            // revoke by id from the output they hold.\n            let response = client.execute_authenticated_with_retry(\n                HttpMethod::Post,\n                \"/api/account/api-keys\",\n                Some(body),\n                Retry::Never,\n                sleeper,\n            )?;\n            if !(200..300).contains(&response.status) {\n                return Err(anyhow::Error::new(classify(&response)));\n            }\n            let created: ApiKeyCreateResponse = decode_json(response)?;\n            write_created_key(out, &created)?;\n            if create.use_locally {\n                save_key_as_local_codewhale_credential(provider_secrets, &created.secret, out)?;\n            }\n            Ok(())\n        }\n        ApiKeysCommand::List => {\n            let response = client.execute_authenticated_with_retry(\n                HttpMethod::Get,\n                \"/api/account/api-keys\",\n                None,\n                Retry::Idempotent,\n                sleeper,\n            )?;\n            if !(200..300).contains(&response.status) {\n                return Err(anyhow::Error::new(classify(&response)));","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/cloud/machine.rs#L898-L934","documentation":"After a machine-token creation request, the CLI classifies any non-2xx HTTP response via classify(&response) and returns it as an error. The message template \"The Codewhale service returned HTTP {status}: {server_message}\" is the server-classified error shape: the request reached the service but was rejected (e.g. auth failure, validation, rate limit).","triggerScenarios":"`codewhale account api-keys create` where the response status is outside 200..300: expired/invalid machine session bearer, 422 validation of the key name, 429 rate limit, or 5xx server error.","commonSituations":"Session token expired before creating a key; duplicate or invalid API key name; hitting creation rate limits; service incident returning 5xx.","solutions":["Re-authenticate so the request carries a valid bearer token","Check the returned server_message and status for the specific cause (validation, rate limit, auth)","Retry after the indicated retry_after delay for 429 responses","Retry later or check service status for 5xx errors"],"exampleFix":"// before\nlet created: ApiKeyCreateResponse = decode_json(response)?;\n// after (defensive check at call site)\nif !(200..300).contains(&response.status) {\n    eprintln!(\"key creation failed: HTTP {} — check session token and key name\", response.status);\n    return Err(anyhow::Error::new(classify(&response)));\n}","handlingStrategy":"try-catch","validationCode":"if !(200..300).contains(&response.status) {\n    return Err(anyhow!(\"HTTP {}: {}\", response.status, response.retry_after.map(|d| d.to_string()).unwrap_or_default()));\n}","typeGuard":null,"tryCatchPattern":"match create_api_key(...) {\n    Ok(created) => write_created_key(out, &created)?,\n    Err(e) if e.to_string().contains(\"returned HTTP\") => {\n        if e.to_string().contains(\"429\") { sleep_with_backoff(); retry(); }\n        else if e.to_string().contains(\"401\")||e.to_string().contains(\"403\") { reauthenticate()?; }\n        else { return Err(e); }\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Refresh the session bearer before long account operations","Handle 429 with retry_after backoff","Validate key names against server rules before creating","Check service status for 5xx before blaming client config"],"tags":["http","api","cloud","auth"],"backgroundTag":"http-error-response","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}