Hmbown/CodeWhale · error · anyhow::Error
No API key provided. Pass --api-key or pipe one via stdin.
Error message
No API key provided. Pass --api-key or pipe one via stdin.
What it means
run_login() with no --api-key falls back to read_api_key_from_stdin(), which first checks io::stdin().is_terminal(). If stdin is an interactive terminal it bails immediately with this message rather than hanging on hidden input; piping is the designed non-interactive path.
Source
Thrown at crates/tui/src/lib.rs:7767
/// Apply the same reasoning-preference precedence as interactive `App`
/// construction to non-TUI runtimes.
///
/// `/model` and the config editor persist this preference in `settings.toml`.
/// Exec, review, workflow, ACP, and runtime-thread launches all begin with a
/// `Config`, so copying the saved value here keeps those entry points from
/// silently falling back to a route classifier or an older config.toml value.
fn apply_saved_reasoning_preference(config: &mut Config, settings: &crate::settings::Settings) {
let Some(reasoning_effort) = settings.reasoning_effort.as_ref() else {
return;
};
config.reasoning_effort = Some(reasoning_effort.clone());
config.reasoning_effort_inferred_from_legacy_alias = false;
}
fn read_api_key_from_stdin() -> Result<String> {
let mut stdin = io::stdin();
if stdin.is_terminal() {
bail!("No API key provided. Pass --api-key or pipe one via stdin.");
}
let mut buffer = String::new();
stdin.read_to_string(&mut buffer)?;
let api_key = buffer.trim().to_string();
if api_key.is_empty() {
bail!("No API key provided via stdin.");
}
Ok(api_key)
}
fn run_login(api_key: Option<String>) -> Result<()> {
let api_key = match api_key {
Some(key) => key,
None => read_api_key_from_stdin()?,
};
let saved = config::save_api_key(&api_key)?;
println!("Saved API key to {}", saved.describe());
Ok(())View on GitHub (pinned to 0c42157ee5)
Solutions
- Pass the key explicitly: `codewhale login --api-key <key>`
- Or pipe it: `printf '%s' "$CODEWHALE_API_KEY" | codewhale login`
- In scripts, always source the key from a variable or secret store rather than expecting a prompt
Example fix
// before (interactive tty, no key) $ codewhale login Error: No API key provided. Pass --api-key or pipe one via stdin. // after $ codewhale login --api-key "$CODEWHALE_API_KEY" // or: $ printf '%s' "$CODEWHALE_API_KEY" | codewhale login
Defensive patterns
Strategy: validation
Validate before calling
: "${CODEWHALE_API_KEY:?set CODEWHALE_API_KEY or pass --api-key}"
codewhale login --api-key "$CODEWHALE_API_KEY" Prevention
- Fail fast on missing key variables with : "${VAR:?}"
- Store the key in the environment or a secret manager, not in shell history
When it happens
Trigger: Running `codewhale login` without --api-key from an interactive shell (stdin is a TTY). Any piped invocation takes the stdin branch instead and never sees this message.
Common situations: Typing `codewhale login` expecting a password-style hidden prompt (there is none); forgetting the flag during a quick local test.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- No API key provided via stdin.
- API key input is unexpectedly large
- interactive key entry requires a terminal; use `--api-key-st
- Kimi is API-key-only in Codewhale. Create a key at https://p
- empty API key provided
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/e38cc9ff84ca4b74.
Report an issue: GitHub.