Hmbown/CodeWhale · error
API key id must be lowercase hex characters — the part…
Error message
API key id must be {KEY_ID_LEN} lowercase hex characters — the part after `cwc_key_` in the display prefix. Run `codewhale account api-keys list` to see them. What it means
The key-id argument must be exactly KEY_ID_LEN lowercase hex characters — the segment immediately after `cwc_key_` in the key's display prefix. The validator trims the input, checks length and hex-ness (digits and a-f only), and bails with instructions to find ids via `codewhale account api-keys list`.
Solutions
- Run `codewhale account api-keys list` and copy the id exactly as shown
- Take only the substring after `cwc_key_` (the 24-hex segment), not the whole key
- Lowercase any uppercase hex characters
- Trim whitespace and strip surrounding quotes
Example fix
// before codewhale account api-keys revoke cwc_key_A1B2C3D4E5F60718293A4B5C // after codewhale account api-keys revoke a1b2c3d4e5f60718293a4b5c
Defensive patterns
Strategy: validation
Validate before calling
fn key_id_ok(id: &str, len: usize) -> bool {
let id = id.trim();
id.len() == len && id.bytes().all(|b| b.is_ascii_digit() || (b'a'..=b'f').contains(&b))
} Prevention
- Copy ids directly from `codewhale account api-keys list`, never from a full key token
- Remember the id is only the 24-hex segment after `cwc_key_`
- Lowercase hex characters before passing them
When it happens
Trigger: Passing a key id to a revoke/delete command that is the wrong length, contains uppercase hex (A–F), includes the whole key/prefix, or contains non-hex characters (crates/cli/src/cloud/machine.rs:855).
Common situations: Passing the full key token instead of just the id after `cwc_key_`, copying the id with surrounding whitespace or quotes, uppercase hex from a formatted display, or confusing the key id with a key label.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- API key contains invalid control characters
- API key must be - UTF-8 bytes
- API key name must be 1
- is not a well-formed Codewhale API key, so it was not sent…
- A positive pull request number is required
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/b265c3c17a00021a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/cloud/machine.rs:855
normalized.push(scope.to_string());
}
}
Ok(Some(normalized))
}
/// The 24-hex key id, checked locally.
///
/// This is a paste check, not an existence check: the server answers 404
/// identically for a malformed id, an unknown id, and another account's id, so
/// nothing here can or should try to distinguish them.
pub(crate) fn validate_key_id(id: &str) -> Result<&str> {
let id = id.trim();
if id.len() != KEY_ID_LEN
|| !id
.bytes()
.all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
{
bail!(
"API key id must be {KEY_ID_LEN} lowercase hex characters — the part after `cwc_key_` \
in the display prefix. Run `codewhale account api-keys list` to see them."
);
}
Ok(id)
}
/// Refuse a management command that would be authenticated by a machine key.
///
/// The server would answer 403 `api_key_route_denied`, but a local refusal is
/// better: it never puts the credential on the wire, and it names the fix.
/// This is the load-bearing rule of the whole design — a stolen key must not
/// be able to bootstrap a successor that outlives the revocation of the key
/// that was stolen — so the CLI states it rather than discovering it.
pub(crate) fn reject_machine_key_for_management(
machine: &MachineKeyEnv,
has_session: bool,
) -> Result<()> {View on GitHub (pinned to 73e0f67d83)