{"record":{"id":"16f1cc17c9aa0af6","repo":"Hmbown/CodeWhale","slug":"api-key-on-stdin-exceeds-the-8-kib-limit","errorCode":null,"errorMessage":"API key on stdin exceeds the 8 KiB limit","messagePattern":"API key on stdin exceeds the 8 KiB limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/lib.rs","lineNumber":5532,"sourceCode":"    };\n    metrics::run(metrics::MetricsArgs {\n        json: args.json,\n        since,\n    })\n}\n\n/// Maximum bytes read for an API key on stdin. Keys are short; anything\n/// larger is a piped file, not a key.\nconst MAX_STDIN_API_KEY_BYTES: u64 = 8 * 1024;\n\nfn read_api_key_from_stdin() -> Result<String> {\n    let mut input = String::new();\n    io::stdin()\n        .take(MAX_STDIN_API_KEY_BYTES + 1)\n        .read_to_string(&mut input)\n        .context(\"failed to read api key from stdin\")?;\n    if input.len() as u64 > MAX_STDIN_API_KEY_BYTES {\n        bail!(\"API key on stdin exceeds the 8 KiB limit\");\n    }\n    let key = input.trim().to_string();\n    if key.is_empty() {\n        bail!(\"empty API key provided\");\n    }\n    Ok(key)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use clap::error::ErrorKind;\n    use codewhale_config::{ModelSource, ProviderSource};\n    use std::ffi::OsString;\n    use std::sync::{Mutex, OnceLock};\n\n    fn parse_ok(argv: &[&str]) -> Cli {\n        Cli::try_parse_from(argv).unwrap_or_else(|err| panic!(\"parse failed for {argv:?}: {err}\"))","sourceCodeStart":5514,"sourceCodeEnd":5550,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/lib.rs#L5514-L5550","documentation":"The stdin API-key reader caps input at MAX_STDIN_API_KEY_BYTES (8 KiB). It deliberately reads one extra byte via take(limit + 1) so an over-long input is detected exactly, then bails rather than truncating or accepting an oversized key.","triggerScenarios":"Piping or typing an API key into the stdin-reading subcommand whose total length exceeds 8192 bytes (8 KiB), e.g. `cat huge-key.txt | codewhale ... api-key-from-stdin`.","commonSituations":"Pasting a whole JSON credential blob or PEM instead of the bare key; accidentally piping a file of keys; concatenated env output including newlines and multiple secrets.","solutions":["Trim the input to just the API key — only the bare token, ≤ 8 KiB: `head -c 8192` no; instead extract the correct field.","If the credential genuinely exceeds 8 KiB, use the alternative non-stdin key configuration path (config/provider key store) rather than stdin.","Verify with `wc -c` that the key input is under 8193 bytes: `wc -c key.txt`."],"exampleFix":"// before\ncat full-credential-bundle.json | codewhale providers set-key --stdin\n// after\njq -r .api_key full-credential-bundle.json | codewhale providers set-key --stdin","handlingStrategy":"validation","validationCode":"let key = std::fs::read_to_string(\"key.txt\")?;\nif key.trim().is_empty() || key.len() > 8 * 1024 {\n    eprintln!(\"api key must be non-empty and at most 8 KiB\");\n}","typeGuard":null,"tryCatchPattern":"match read_api_key_from_stdin() {\n    Err(e) if e.to_string().contains(\"exceeds the 8 KiB limit\") => {\n        eprintln!(\"input too large — extract the bare key token, not a whole credential file\");\n    }\n    Err(e) => return Err(e),\n    Ok(k) => use_key(k),\n}","preventionTips":["Pipe only the bare key token; never a JSON bundle, PEM, or multi-key file.","Check `wc -c` on the source before piping.","Use the config/provider key store for oversized credentials instead of stdin."],"tags":["cli","stdin","validation"],"backgroundTag":"payload-too-large","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}