Hmbown/CodeWhale · error

API key name must be 1

Error message

API key name must be 1-{MAX_KEY_NAME_CHARS} characters, start with a letter or digit, and contain only letters, digits, spaces, and `. _ : @ / -`.

What it means

Local pre-flight validation of a user-supplied API key name, mirroring the server regex `/^[A-Za-z0-9][A-Za-z0-9 ._:@\/-]{0,63}$/`. It fails fast client-side so an invalid name costs a message instead of a network round trip.

Solutions

  1. Use a name matching the regex: start with a letter/digit, ≤64 chars, only `A-Za-z0-9 . _ : @ / -` and spaces.
  2. Trim whitespace and strip shell-mangled characters from scripts.
  3. Shorten auto-generated names to fit the 64-char limit.

Example fix

// before
codewhale account api-keys create --name "ci key (prod)!"
// after
codewhale account api-keys create --name "ci key prod-01"
Defensive patterns

Strategy: validation

Validate before calling

fn valid_key_name(name: &str) -> bool {
    let n = name.chars().count();
    n >= 1 && n <= 64
        && name.chars().next().map_or(false, |c| c.is_ascii_alphanumeric())
        && name.chars().all(|c| c.is_ascii_alphanumeric() || " ._:@/-".contains(c))
}

Type guard

fn valid_key_name(name: &str) -> bool {
    let n = name.chars().count();
    n >= 1 && n <= 64
        && name.chars().next().map_or(false, |c| c.is_ascii_alphanumeric())
        && name.chars().all(|c| c.is_ascii_alphanumeric() || " ._:@/-".contains(c))
}

Prevention

When it happens

Trigger: Creating or renaming an API key with a name that is empty, longer than MAX_KEY_NAME_CHARS (64), starts with a non-alphanumeric character, or contains characters outside letters, digits, spaces, and `. _ : @ / -`.

Common situations: Names with quotes, emoji, `#`, or leading `-`/`_`; scripted names with shell-expanded odd characters; names over 64 chars generated from hostnames or timestamps.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/7ace602afad4e3fd. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/cloud/machine.rs:793

    #[arg(long = "expires-in-days", value_parser = clap::value_parser!(u32).range(1..=i64::from(MAX_EXPIRY_DAYS)))]
    expires_in_days: Option<u32>,
    /// Repeatable. Omit for all of `account:read`, `agent:run`, `models:infer`.
    #[arg(long = "scope", value_name = "SCOPE")]
    scopes: Vec<String>,
    /// Also save the new secret as this machine's local `codewhale` provider
    /// credential, so the CLI can immediately use Codewhale API models.
    ///
    /// The key never leaves this machine: it goes to the same secret store
    /// `codewhale auth` writes, and nothing is uploaded anywhere.
    #[arg(long = "use", default_value_t = false)]
    use_locally: bool,
}

/// `/^[A-Za-z0-9][A-Za-z0-9 ._:@\/-]{0,63}$/`, checked locally so a bad name
/// costs a message instead of a round trip.
pub(crate) fn validate_key_name(name: &str) -> Result<&str> {
    let invalid = || {
        anyhow!(
            "API key name must be 1-{MAX_KEY_NAME_CHARS} characters, start with a letter or \
digit, and contain only letters, digits, spaces, and `. _ : @ / -`."
        )
    };
    let mut characters = name.chars();
    let Some(first) = characters.next() else {
        return Err(invalid());
    };
    if !first.is_ascii_alphanumeric() || name.chars().count() > MAX_KEY_NAME_CHARS {
        return Err(invalid());
    }
    if characters.any(|character| {
        !character.is_ascii_alphanumeric()
            && !matches!(character, ' ' | '.' | '_' | ':' | '@' | '/' | '-')
    }) {
        return Err(invalid());
    }
    Ok(name)

View on GitHub (pinned to 73e0f67d83)