{"record":{"id":"cc4edb5e96c06d83","repo":"Hmbown/CodeWhale","slug":"invalid-input","errorCode":null,"errorMessage":"Invalid input","messagePattern":"Invalid input","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"crates/tui/src/lib.rs","lineNumber":7813,"sourceCode":"        bail!(\"No saved sessions found.\");\n    }\n\n    println!(\"Select a session to resume:\");\n    for (idx, session) in sessions.iter().enumerate() {\n        println!(\"  {:>2}. {} ({})\", idx + 1, session.title, session.id);\n    }\n    print!(\"Enter a number (or press Enter to cancel): \");\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 session selected.\");\n    }\n    let idx: usize = input\n        .parse()\n        .map_err(|_| anyhow::anyhow!(\"Invalid input\"))?;\n    let session = sessions\n        .get(idx.saturating_sub(1))\n        .ok_or_else(|| anyhow::anyhow!(\"Selection out of range\"))?;\n    Ok(session.id.clone())\n}\n\nasync fn run_review(config: &Config, args: ReviewArgs) -> Result<()> {\n    use crate::client::DeepSeekClient;\n\n    let diff = collect_diff(&args)?;\n    if diff.trim().is_empty() {\n        bail!(\"No diff to review.\");\n    }\n    validate_review_receipt_args(&args)?;\n    if args.check_receipt {\n        return run_review_receipt_check(&diff, &args);\n    }\n","sourceCodeStart":7795,"sourceCodeEnd":7831,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/lib.rs#L7795-L7831","documentation":"When resume runs with no ID and a terminal is available, Codewhale prints a numbered session list and reads one line from stdin. The trimmed line must parse as usize; non-numeric input like 'abc' or '1a' fails with 'Invalid input'. Empty input cancels earlier with 'No session selected.'.","triggerScenarios":"Typing letters, punctuation, or mixed text at the picker prompt; piping unexpected text into stdin from a script; terminals injecting escape sequences on paste.","commonSituations":"Muscle memory types a session name or ID prefix instead of its list number; automation feeds non-numeric stdin to an interactive command.","solutions":["Enter the 1-based number shown next to the session, or press Enter on an empty line to cancel","In scripts, avoid the picker entirely: pass codewhale resume <SESSION_ID>","When pasting, paste digits only","Re-run and choose again after a typo"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let input = read_line_trimmed();\nif !input.is_empty() && input.parse::<usize>().is_err() {\n    eprintln!(\"enter the 1-based list number, or press Enter to cancel\");\n}","typeGuard":"fn is_valid_selection_input(input: &str) -> bool {\n    let t = input.trim();\n    t.is_empty() || t.parse::<usize>().is_ok()\n}","tryCatchPattern":null,"preventionTips":["Type the 1-based list number, not a session name","Use explicit session IDs in automation instead of the interactive picker","Press Enter on an empty line to cancel cleanly"],"tags":["rust","cli","input-validation","sessions"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}