{"record":{"id":"232c4793f797c9f3","repo":"Hmbown/CodeWhale","slug":"external-credential-consent-was-not-saved-non-int","errorCode":null,"errorMessage":"external credential consent was not saved: non-interactive use requires explicit --yes after reviewing the preview","messagePattern":"external credential consent was not saved: non-interactive use requires explicit --yes after reviewing the preview","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/cli/src/lib.rs","lineNumber":4332,"sourceCode":"            \"  access: read_only ({})\",\n            codewhale_config::EXTERNAL_CREDENTIAL_READ_ONLY_SEMANTICS\n        ),\n        \"  managed: unavailable (no reviewed schema-safe preservation adapter)\".to_string(),\n        format!(\n            \"  revoke: codewhale auth external-revoke --provider {}\",\n            provider.as_str()\n        ),\n    ]\n}\n\nfn confirm_external_consent(yes: bool) -> Result<()> {\n    use std::io::IsTerminal;\n\n    if yes {\n        return Ok(());\n    }\n    if !std::io::stdin().is_terminal() {\n        bail!(\n            \"external credential consent was not saved: non-interactive use requires explicit --yes after reviewing the preview\"\n        );\n    }\n    confirm_external_consent_answer(&mut std::io::stdin().lock(), &mut std::io::stdout().lock())\n}\n\nfn confirm_external_consent_answer(\n    reader: &mut impl std::io::BufRead,\n    writer: &mut impl std::io::Write,\n) -> Result<()> {\n    write!(writer, \"Type 'yes' to grant this exact read-only access: \")?;\n    writer.flush()?;\n    let mut answer = String::new();\n    reader\n        .read_line(&mut answer)\n        .context(\"reading external credential consent confirmation\")?;\n    if answer.trim() != \"yes\" {\n        bail!(\"external credential consent cancelled; no configuration was changed\");","sourceCodeStart":4314,"sourceCodeEnd":4350,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/lib.rs#L4314-L4350","documentation":"The consent confirmation refuses to save when stdin is not a TTY and `--yes` was not passed. Because a non-interactive caller cannot answer the yes/no prompt, the flow bails rather than silently skipping consent.","triggerScenarios":"Running the external credential consent command from a pipe, CI job, or subprocess (stdin not a terminal) without `--yes`.","commonSituations":"Scripted setup pipelines; docker/CI runs; invoking via tools that detach stdin; forgotten `--yes` in automation that worked interactively.","solutions":["Review the printed preview lines, then re-run with `--yes` to record consent","Or run the command interactively in a terminal to answer the prompt"],"exampleFix":"// before\ncodewhale auth external --provider grok --mode read-only < /dev/null\n// after\ncodewhale auth external --provider grok --mode read-only --yes < /dev/null","handlingStrategy":"validation","validationCode":"if [ ! -t 0 ] && ! grep -q -- '--yes' <<< \"$flags\"; then echo \"non-interactive: add --yes\"; exit 1; fi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass --yes in CI/non-interactive contexts after reviewing the preview once","Detect TTY (`[ -t 0 ]`) in scripts before interactive commands"],"tags":["cli","consent","non-interactive","stdin"],"backgroundTag":"missing-required-flag","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"}