Hmbown/CodeWhale · warning · anyhow::Error
key label must contain 1-{MAX_KEY_LABEL_CHARS} characters
Error message
key label must contain 1-{MAX_KEY_LABEL_CHARS} characters What it means
Key labels (e.g. for `codewhale cloud key add --label`) are normalized by collapsing whitespace, then must be 1-80 characters with no control characters. This bail fires when the normalized label is empty, longer than 80 chars, or contains control bytes - for example a label made only of spaces collapses to empty and is rejected.
Source
Thrown at crates/cli/src/cloud.rs:895
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()
|| label.chars().count() > MAX_KEY_LABEL_CHARS
|| label.chars().any(is_ascii_control)
{
bail!("key label must contain 1-{MAX_KEY_LABEL_CHARS} characters");
}
Ok(label)
}
fn is_ascii_control(character: char) -> bool {
character <= '\u{001f}' || character == '\u{007f}'
}
fn resolve_local_key(
config: &ConfigStore,
secrets: &Secrets,
provider: CloudProvider,
) -> Result<Option<String>> {
let kind = provider.local_kind();
let provider_config = config.config.providers.for_provider(kind);
let from_config = provider_config.api_key.clone().or_else(|| {
(kind == ProviderKind::Deepseek)
.then(|| config.config.api_key.clone())View on GitHub (pinned to 0c42157ee5)
Solutions
- Provide a short non-empty label (default to something like the hostname or date if scripting: --label "${LABEL:-ci-$(date +%F)}")
- Trim the label to <=80 characters before passing it
- Remove newlines/tabs from scripted labels: --label "$(echo "$LABEL" | tr '\n' ' ')"
- Check for unset variables in scripts (set -u) so labels never silently become empty
Example fix
# before
codewhale cloud key add --label "" # empty after collapse -> error
# after
codewhale cloud key add --label "${LABEL:-laptop-$(date +%F)}" Defensive patterns
Strategy: validation
Validate before calling
const MAX_KEY_LABEL_CHARS: usize = 80;
fn label_ok(raw: &str) -> bool {
let normalized = raw.split_whitespace().collect::<Vec<_>>().join(" ");
!normalized.is_empty()
&& normalized.chars().count() <= MAX_KEY_LABEL_CHARS
&& !normalized.chars().any(|c| c <= '\u{001f}' || c == '\u{007f}')
} Type guard
fn is_valid_label(label: &str) -> bool {
let n = label.split_whitespace().collect::<Vec<_>>().join(" ");
!n.is_empty() && n.chars().count() <= 80
&& !n.chars().any(|c| c <= '\u{001f}' || c == '\u{007f}')
} Prevention
- Default labels in scripts: --label "${LABEL:-ci-$(date +%F)}"
- Truncate long ticket titles to 80 chars before passing
- set -u in scripts so label variables cannot silently be empty
When it happens
Trigger: Passing --label ' ' (whitespace-only), a 100+ character description, or a label with embedded tabs/newlines; the value is whitespace-collapsed first so 'a\n\nb' passes but ' \t ' does not.
Common situations: Scripted key creation where the label variable is empty or unset (expands to blank); labels copied from ticket titles that exceed 80 chars; multi-line paste into a label prompt.
Related errors
- API key must be {MIN_API_KEY_BYTES}-{MAX_API_KEY_BYTES} UTF-
- API key contains invalid control characters
- The Codewhale service returned an account without an ID
- The Codewhale service returned an invalid user code
- The Codewhale service returned an invalid device authorizati
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/4136641efd7cb20f.
Report an issue: GitHub.