{"record":{"id":"684f796516a7f503","repo":"Hmbown/CodeWhale","slug":"api-key-must-be-min-api-key-bytes-max-api-key-b","errorCode":null,"errorMessage":"API key must be {MIN_API_KEY_BYTES}-{MAX_API_KEY_BYTES} UTF-8 bytes","messagePattern":"API key must be (.+?)-(.+?) UTF-8 bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/cloud.rs","lineNumber":1135,"sourceCode":"    }\n    Ok(())\n}\n\nfn validate_device_code(code: &str) -> Result<()> {\n    if code.len() != 43\n        || !code\n            .bytes()\n            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_'))\n    {\n        bail!(\"The Codewhale service returned an invalid device authorization response\");\n    }\n    Ok(())\n}\n\nfn validate_api_key(key: &str) -> Result<()> {\n    let bytes = key.len();\n    if bytes < MIN_API_KEY_BYTES || bytes as u64 > MAX_API_KEY_BYTES {\n        bail!(\"API key must be {MIN_API_KEY_BYTES}-{MAX_API_KEY_BYTES} UTF-8 bytes\");\n    }\n    if key.chars().any(is_ascii_control) {\n        bail!(\"API key contains invalid control characters\");\n    }\n    Ok(())\n}\n\nfn validate_label(label: &str) -> Result<String> {\n    let label = label.split_whitespace().collect::<Vec<_>>().join(\" \");\n    if label.is_empty()\n        || label.chars().count() > MAX_KEY_LABEL_CHARS\n        || label.chars().any(is_ascii_control)\n    {\n        bail!(\"key label must contain 1-{MAX_KEY_LABEL_CHARS} characters\");\n    }\n    Ok(label)\n}\n","sourceCodeStart":1117,"sourceCodeEnd":1153,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/cloud.rs#L1117-L1153","documentation":"validate_api_key enforces that a Codewhale API key falls within the allowed byte-length range (MIN_API_KEY_BYTES..MAX_API_KEY_BYTES). The CLI bails before sending anything to the server when the provided key string is too short or too long. This is a client-side guard so a truncated or mangled paste fails fast locally instead of producing a server 401.","triggerScenarios":"Calling the CLI's api-key import/creation paths (validate_api_key in crates/cli/src/cloud.rs:1135) with a --api-key value whose UTF-8 byte length is below MIN_API_KEY_BYTES or above MAX_API_KEY_BYTES.","commonSituations":"Pasting only part of a key (truncated clipboard), shell quoting stripping characters, an extra file or whitespace appended making the value too long, or copying a different provider's key that has a different length.","solutions":["Re-copy the full API key and pass it again, checking its length matches the documented format","Inspect the value with `echo -n \"$KEY\" | wc -c` to confirm byte count before retrying","If input comes from a file or stdin, ensure no stray bytes (e.g. concatenated lines) were included","Create a fresh key with `codewhale account api-keys create` if the original is unrecoverable"],"exampleFix":"// before\ncodewhale account api-keys import --api-key \"cwc_key_abc123\"  # truncated\n// after\ncodewhale account api-keys import --api-key \"cwc_key_0a1b...<24 hex>_<43 chars>\"","handlingStrategy":"validation","validationCode":"fn key_len_ok(key: &str, min: u64, max: u64) -> bool {\n    let n = key.len() as u64;\n    n >= min && n <= max\n}\n// call before import: if !key_len_ok(&key, MIN, MAX) { /* fix input */ }","typeGuard":"fn is_plausible_api_key(s: &str) -> bool {\n    s.starts_with(\"cwc_key_\") && s.len() >= 32 && s.len() <= 256\n}","tryCatchPattern":null,"preventionTips":["Store keys in a file/secret manager and pass via --api-key-stdin (it trims and validates)","Check byte count with `wc -c` before importing a key","Never hand-edit a key token; copy it whole from `codewhale account api-keys list`"],"tags":["cli","validation","api-key"],"backgroundTag":"invalid-argument-format","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}