{"record":{"id":"0004a11a170f7674","repo":"Hmbown/CodeWhale","slug":"no-selection-made","errorCode":null,"errorMessage":"No selection made.","messagePattern":"No selection made\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/remote_setup/mod.rs","lineNumber":253,"sourceCode":"// ---------------------------------------------------------------------------\n// Prompt helpers (reuse the stdin pattern from main.rs `pick_session_id`)\n// ---------------------------------------------------------------------------\n\n/// Print a numbered menu, read a 1-based selection from stdin, return the index.\nfn prompt_choice(title: &str, options: &[String]) -> Result<usize> {\n    println!();\n    println!(\"{title}:\");\n    for (idx, opt) in options.iter().enumerate() {\n        println!(\"  {:>2}. {}\", idx + 1, opt);\n    }\n    print!(\"Enter a number: \");\n    io::stdout().flush()?;\n\n    let mut input = String::new();\n    io::stdin().read_line(&mut input)?;\n    let input = input.trim();\n    if input.is_empty() {\n        bail!(\"No selection made.\");\n    }\n    let n: usize = input\n        .parse()\n        .map_err(|_| anyhow::anyhow!(\"Invalid input: {input}\"))?;\n    options\n        .get(n.saturating_sub(1))\n        .map(|_| n - 1)\n        .ok_or_else(|| anyhow::anyhow!(\"Selection out of range\"))\n}\n\n/// Generate a runtime token from two random v4 UUIDs (OS CSPRNG via uuid),\n/// matching the existing token-generation pattern in this crate.\nfn generate_runtime_token() -> String {\n    let a = uuid::Uuid::new_v4().simple().to_string();\n    let b = uuid::Uuid::new_v4().simple().to_string();\n    format!(\"{a}{b}\")\n}\n","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/remote_setup/mod.rs#L235-L271","documentation":"The interactive prompt_choice helper reads a numbered choice from stdin. When the trimmed input is empty (user pressed Enter on a blank line, or stdin was closed/redirected from an empty source) it bails with 'No selection made.' This fires only in interactive flows; non-interactive mode never reaches the prompt.","triggerScenarios":"Pressing Enter without typing a number at any 'Enter a number:' prompt in remote setup (cloud target, bridge, provider selection); piping an empty line or /dev/null into the command while running it without --non-interactive; a crashed terminal that closes stdin mid-prompt.","commonSituations":"Users hit Enter hoping for a default; scripts drive the interactive path with empty stdin; CI accidentally omits --non-interactive so the process prompts into a pipe that immediately EOFs or yields blank lines.","solutions":["Re-run and enter a number corresponding to one of the listed options.","In automation, always pass --non-interactive plus all required flags so no stdin prompt is attempted.","If stdin is being redirected, ensure the piped input contains a valid line like '1' rather than an empty line."],"exampleFix":"# before\nprintf '' | codewhale remote-setup   # prompt reads empty input -> No selection made.\n\n# after\ncodewhale remote-setup --non-interactive --cloud <slug> --bridge <slug> --provider <slug>","handlingStrategy":"validation","validationCode":"# Shell: never drive the interactive prompt blindly; either supply stdin or go non-interactive\nif [ -t 0 ]; then\n  codewhale remote-setup   # interactive terminal, user types choices\nelse\n  codewhale remote-setup --non-interactive --cloud \"$CODEWHALE_CLOUD\" --bridge \"$CODEWHALE_BRIDGE\" --provider \"$CODEWHALE_PROVIDER\"\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use --non-interactive with explicit flags when stdin is not a TTY.","Document that blank Enter is not a valid selection at the numbered prompts.","When piping answers, ensure each line contains a valid option number."],"tags":["cli","interactive-prompt","stdin","user-input","rust"],"backgroundTag":"empty-user-input","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}