Hmbown/CodeWhale · warning
Invalid input
Error message
Invalid input: {input} What it means
prompt_choice parses interactive menu input as a usize index. Any non-empty input that is not a valid unsigned integer (e.g. letters, negative numbers, floats) produces this error; empty input produces a separate 'No selection made' error.
Solutions
- Enter the numeric option number shown next to the choice (1-based)
- Trim whitespace/paste artifacts and retry
- Only digits are accepted — no letters, signs, or decimals
- For automation, pipe the index (e.g. `echo 2 |`) rather than the option name
Example fix
// before Cloud: aws // after Cloud: 2 # numeric position of 'aws' in the list
Defensive patterns
Strategy: try-catch
Validate before calling
let t = input.trim();
if t.is_empty() || t.parse::<usize>().is_err() {
eprintln!("Enter a numeric option, e.g. 1");
} Try / catch
match prompt_choice(&prompt, &options) {
Err(e) if e.to_string().starts_with("Invalid input") => {
// re-prompt once with a hint
eprintln!("{e} — enter the option's number");
prompt_choice(&prompt, &options)
}
other => other,
} Prevention
- Always answer menu prompts with the numeric index
- Trim pasted input and strip stray characters
- For automation, pipe digits only
- Read the menu before answering; do not type option names
When it happens
Trigger: At a remote setup prompt, typing text or a malformed number instead of the numeric option number (e.g. 'aws', '1.5', '-1', or a number with stray characters).
Common situations: Users typing the option's name instead of its number, pasting values with whitespace/characters, keyboard locale issues, or automated input feeding wrong tokens.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Selection out of range
- invalid duration component
- invalid header pair ' ', expected name=value
- No session selected.
- stdin is not a terminal; pass --yes to confirm the…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/b811e621bae4e98c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/remote_setup/mod.rs:257
/// Print a numbered menu, read a 1-based selection from stdin, return the index.
fn prompt_choice(title: &str, options: &[String]) -> Result<usize> {
println!();
println!("{title}:");
for (idx, opt) in options.iter().enumerate() {
println!(" {:>2}. {}", idx + 1, opt);
}
print!("Enter a number: ");
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let input = input.trim();
if input.is_empty() {
bail!("No selection made.");
}
let n: usize = input
.parse()
.map_err(|_| anyhow::anyhow!("Invalid input: {input}"))?;
options
.get(n.saturating_sub(1))
.map(|_| n - 1)
.ok_or_else(|| anyhow::anyhow!("Selection out of range"))
}
/// Generate a runtime token from two random v4 UUIDs (OS CSPRNG via uuid),
/// matching the existing token-generation pattern in this crate.
fn generate_runtime_token() -> String {
let a = uuid::Uuid::new_v4().simple().to_string();
let b = uuid::Uuid::new_v4().simple().to_string();
format!("{a}{b}")
}
#[cfg(test)]
mod tests {
use super::*;
View on GitHub (pinned to 73e0f67d83)