Hmbown/CodeWhale · error

API key input is unexpectedly large

Error message

API key input is unexpectedly large

What it means

parse_key_input guards the stdin path for API key entry: if the raw byte buffer read from stdin exceeds MAX_API_KEY_STDIN_BYTES it bails before decoding. This is a sanity/DoS bound — a legitimate key is far smaller, so an oversized input means the wrong data was piped in.

Solutions

  1. Pipe only the key itself: `printf '%s' 'cwc_key_...' | codewhale ... --api-key-stdin`
  2. Check the input size with `wc -c < keyfile` before piping
  3. Ensure the key file contains only the single key line (no concatenated data)
  4. Use --api-key with the value directly if stdin piping is unnecessary

Example fix

// before
cat notes-and-key.txt | codewhale account api-keys import --api-key-stdin
// after
grep '^cwc_key_' notes-and-key.txt | codewhale account api-keys import --api-key-stdin
Defensive patterns

Strategy: validation

Validate before calling

// shell check before piping
[ "$(wc -c < keyfile)" -le 1024 ] || { echo "key input too large"; exit 1; }

Prevention

When it happens

Trigger: Running a command with --api-key-stdin and piping input whose total byte length exceeds MAX_API_KEY_STDIN_BYTES (crates/cli/src/cloud.rs:1235), e.g. `cat largefile | codewhale ... --api-key-stdin`.

Common situations: Piping a whole file intended to contain only the key, accidentally redirecting the wrong file, a script that echoes a large blob plus the key, or forgetting the key file was appended to.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at crates/cli/src/cloud.rs:1235

        return None;
    }
    std::env::var(variable)
        .ok()
        .filter(|value| !value.trim().is_empty())
}

fn read_key_from_stdin() -> Result<String> {
    let mut bytes = Vec::new();
    io::stdin()
        .take(MAX_API_KEY_STDIN_BYTES + 1)
        .read_to_end(&mut bytes)
        .context("failed to read API key from stdin")?;
    parse_key_input(bytes)
}

fn parse_key_input(bytes: Vec<u8>) -> Result<String> {
    if bytes.len() as u64 > MAX_API_KEY_STDIN_BYTES {
        bail!("API key input is unexpectedly large");
    }
    let value = String::from_utf8(bytes).context("API key from stdin is not valid UTF-8")?;
    let value = value.trim().to_string();
    validate_api_key(&value)?;
    Ok(value)
}

fn read_key_hidden(provider: &str) -> Result<String> {
    if !io::stdin().is_terminal() {
        bail!("interactive key entry requires a terminal; use `--api-key-stdin` for piped input");
    }
    let term = console::Term::stderr();
    term.write_str(&format!("Enter {provider} API key: "))
        .context("failed to write API key prompt")?;
    let value = term
        .read_secure_line()
        .context("failed to read API key securely")?;
    term.write_line("").ok();

View on GitHub (pinned to 73e0f67d83)