{"record":{"id":"add86a9d9d93a287","repo":"BloopAI/vibe-kanban","slug":"failed-to-read-email","errorCode":null,"errorMessage":"Failed to read email","messagePattern":"Failed to read email","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/review/src/main.rs","lineNumber":78,"sourceCode":"    println!(\"Full terms and conditions and privacy policy: https://review.fast/terms\");\n    println!();\n    println!(\"Press Enter to accept and continue...\");\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).ok();\n}\n\nfn prompt_email(config: &mut config::Config) -> String {\n    use dialoguer::Input;\n\n    let mut input: Input<String> =\n        Input::new().with_prompt(\"Email address (we'll send a link to the review here, no spam)\");\n\n    if let Some(ref saved_email) = config.email {\n        input = input.default(saved_email.clone());\n    }\n\n    let email: String = input.interact_text().expect(\"Failed to read email\");\n\n    // Save email for next time\n    config.email = Some(email.clone());\n    if let Err(e) = config.save() {\n        debug!(\"Failed to save config: {}\", e);\n    }\n\n    email\n}\n\nfn create_spinner(message: &str) -> ProgressBar {\n    let spinner = ProgressBar::new_spinner();\n    spinner.set_style(\n        ProgressStyle::default_spinner()\n            .template(\"{spinner:.green} {msg}\")\n            .expect(\"Invalid spinner template\"),\n    );\n    spinner.set_message(message.to_string());","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/review/src/main.rs#L60-L96","documentation":"`Input::interact_text()` from the dialoguer crate returns a Result; it errors when reading from stdin fails (e.g. no TTY, EOF, or interrupted terminal). The code expects success, so a failed interactive prompt panics with \"Failed to read email\" in the review CLI's `prompt_email` step.","triggerScenarios":"`prompt_email` runs and the terminal read fails: running non-interactively (CI, piped stdin like `echo | review`, no TTY), user presses Ctrl+D (EOF), or the terminal is closed mid-prompt.","commonSituations":"Running the PR review tool in CI or scripted environments without an interactive terminal; users piping input; Ctrl+C/Ctrl+D during the prompt; Windows console edge cases.","solutions":["Detect non-interactive environments first (atty/is-terminal on stdin) and require the email via a CLI flag or config file instead of prompting","Replace expect with match on interact_text(): on error, print a friendly message and exit with a nonzero code","Support an --email argument or REVIEW_EMAIL env var so the prompt can be skipped entirely","Allow retrying the prompt once before exiting"],"exampleFix":"// before\nlet email: String = input.interact_text().expect(\"Failed to read email\");\n// after\nlet email: String = input.interact_text()\n    .context(\"Could not read email from terminal. Pass --email or run interactively.\")?;","handlingStrategy":"validation","validationCode":"if !std::io::stdin().is_terminal() {\n    eprintln!(\"No interactive terminal; pass --email or set REVIEW_EMAIL\");\n    std::process::exit(1);\n}","typeGuard":null,"tryCatchPattern":"let email = match input.interact_text() {\n    Ok(e) => e,\n    Err(e) => { eprintln!(\"Could not read email: {e}\"); std::process::exit(1); }\n};","preventionTips":["Check for a TTY before prompting","Offer --email flag / env var as non-interactive alternatives","Save the email to config so later runs skip the prompt","Handle Ctrl+D/EOF gracefully with a clear message"],"tags":["rust","panic","dialoguer","stdin","cli"],"backgroundTag":"missing-tty-stdin","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}