Hmbown/CodeWhale · error · anyhow::Error
The Codewhale service returned an invalid device authorizati
Error message
The Codewhale service returned an invalid device authorization response
What it means
The device_code from the device-authorization response must be exactly 43 characters of ASCII alphanumeric, hyphen, or underscore - the shape of a base64url-encoded 32-byte token. This bail fires when the token has a different length or contains characters like '=', '+', or '/', meaning the response is malformed or from an incompatible service version.
Source
Thrown at crates/cli/src/cloud.rs:873
|| bytes[4] != b'-'
|| bytes[9] != b'-'
|| bytes
.iter()
.enumerate()
.any(|(index, byte)| !matches!(index, 4 | 9) && !ALPHABET.contains(byte))
{
bail!("The Codewhale service returned an invalid user code");
}
Ok(())
}
fn validate_device_code(code: &str) -> Result<()> {
if code.len() != 43
|| !code
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_'))
{
bail!("The Codewhale service returned an invalid device authorization response");
}
Ok(())
}
fn validate_api_key(key: &str) -> Result<()> {
let bytes = key.len();
if bytes < MIN_API_KEY_BYTES || bytes as u64 > MAX_API_KEY_BYTES {
bail!("API key must be {MIN_API_KEY_BYTES}-{MAX_API_KEY_BYTES} UTF-8 bytes");
}
if key.chars().any(is_ascii_control) {
bail!("API key contains invalid control characters");
}
Ok(())
}
fn validate_label(label: &str) -> Result<String> {
let label = label.split_whitespace().collect::<Vec<_>>().join(" ");
if label.is_empty()View on GitHub (pinned to 0c42157ee5)
Solutions
- Emit the device_code as unpadded base64url (43 chars for 32 bytes of entropy) from the service
- Update the CLI to the version matching the service's device-code encoding
- Verify the full response body is received without truncation (check content-length, proxy buffering)
- For local testing, generate codes with 43 chars from [A-Za-z0-9_-]
Example fix
// before device_code: "c29tZS1kZXZpY2UtY29kZS10b2tlbi1wYWRkZWQ=" // after device_code: "c29tZS1kZXZpY2UtY29kZS10b2tlbi11bnBhZGRlZA" // 43 chars, [A-Za-z0-9_-]
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_device_code(code: &str) -> bool {
code.len() == 43
&& code.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_'))
} Type guard
fn is_valid_device_code(code: &str) -> bool {
code.len() == 43
&& code.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_'))
} Prevention
- Emit device codes as unpadded base64url of 32 random bytes (always 43 chars)
- Property-test the encoder against the validator
- Check for truncation when tokens pass through logs or header-limited proxies
When it happens
Trigger: validate_device_code receives a code with standard base64 padding ('...=='), a 64-char hex token, a JWT, or any length other than 43; also truncated codes cut off by header/line-length limits.
Common situations: A backend switching token encodings (hex, padded base64, JWT) without a CLI update; proxies or logs that truncate long tokens; a mock returning an opaque placeholder string.
Related errors
- The Codewhale service returned an invalid user code
- Codewhale account login timed out; run `codewhale account lo
- The Codewhale service returned an untrusted verification ori
- The Codewhale service returned an account without an ID
- The Codewhale service returned an unsafe verification URL
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/f1beae27741d354f.
Report an issue: GitHub.