{"record":{"id":"f2199b075f413ef7","repo":"coding-horror/basic-computer-games","slug":"failed-to-get-input-f2199b","errorCode":null,"errorMessage":"Failed to get input","messagePattern":"Failed to get input","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"82_Stars/rust/src/main.rs","lineNumber":18,"sourceCode":"use rand::Rng;\nuse std::io;\n\nfn main() {\n    println!(\n        \"{: >39}\\n{: >57}\\n\\n\\n\",\n        \"STARS\", \"CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY\"\n    );\n    // STARS - PEOPLE'S COMPUTER CENTER, MENLO PARK, CA\n    // A IS LIMIT ON NUMBER, M IS NUMBER OF GUESSES\n    let a: u32 = 101;\n    let m: u32 = 7;\n    let mut need_instrut = String::new();\n\n    println!(\"DO YOU WANT INSTRUCTIONS?\");\n    io::stdin()\n        .read_line(&mut need_instrut)\n        .expect(\"Failed to get input\");\n\n    if need_instrut[..1].to_ascii_lowercase().eq(\"y\") {\n        println!(\"I AM THINKING OF A WHOLE NUMBER FROM 1 TO {}\", a - 1);\n        println!(\"TRY TO GUESS MY NUMBER.  AFTER YOU GUESS, I\");\n        println!(\"WILL TYPE ONE OR MORE STARS (*).  THE MORE\");\n        println!(\"STARS I TYPE, THE CLOSER YOU ARE TO MY NUMBER.\");\n        println!(\"ONE STAR (*) MEANS FAR AWAY, SEVEN STARS (*******)\");\n        println!(\"MEANS REALLY CLOSE!  YOU GET {} GUESSES.\\n\\n\", m);\n    }\n\n    loop {\n        println!(\"\\nOK, I AM THINKING OF A NUMBER, START GUESSING.\\n\");\n        let rand_number: i32 = rand::thread_rng().gen_range(1..a) as i32; // generates a random number between 1 and 100\n\n        // GUESSING BEGINS, HUMAN GETS M GUESSES\n        for i in 0..m {\n            let mut guess = String::new();\n            println!(\"YOUR GUESS?\");","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/82_Stars/rust/src/main.rs#L1-L36","documentation":"This panic is triggered by `.expect(\"Failed to get input\")` on `io::stdin().read_line()` at the very start of Stars' `main()` (line 18), when asking whether the player wants instructions. The `.expect` fires on any I/O-level stdin failure. Note that line 20 (`need_instrut[..1]`) would separately panic on empty input with an index-out-of-bounds, but that is a different error from this `read_line` panic.","triggerScenarios":"Stdin returns `Err` or EOF at the instructions prompt. If stdin is closed/redirected, this is the first panic the player hits, before the game even starts. An empty line (just Enter) returns `Ok` with content `\"\\n\"`, so it does *not* trigger this panic — instead it triggers the `[..1]` indexing panic on line 20.","commonSituations":"Non-interactive execution. Running in CI. Stdin redirected from `/dev/null`. No TTY allocated (Docker without `-it`). Process spawned by a GUI without stdin wiring.","solutions":["Replace `.expect` with a `match` that handles EOF gracefully and defaults to skipping instructions.","Guard the `need_instrut[..1]` indexing on line 20 with a length check to prevent the related index-out-of-bounds panic.","For non-interactive use, pipe `\"n\\n\"` or `\"y\\n\"` as the first line of input."],"exampleFix":"// before\nio::stdin()\n    .read_line(&mut need_instrut)\n    .expect(\"Failed to get input\");\n\n// after\nmatch io::stdin().read_line(&mut need_instrut) {\n    Ok(0) => { println!(\"No input detected. Starting game without instructions.\"); }\n    Ok(_) => {}\n    Err(e) => { eprintln!(\"Input error: {}\", e); return; }\n}\n\n// also fix the indexing:\n// before: if need_instrut[..1].to_ascii_lowercase().eq(\"y\")\n// after:  if need_instrut.trim_start().starts_with('y')","handlingStrategy":"validation","validationCode":"// Pre-check stdin and guard against empty input\nuse std::io::IsTerminal;\nif !io::stdin().is_terminal() {\n    eprintln!(\"Warning: non-interactive stdin.\");\n}\n// After reading, guard the indexing:\nif need_instrut.is_empty() { /* skip instructions or default */ }","typeGuard":"// Guard the [..1] indexing with a safe check\nfn wants_instructions(input: &str) -> bool {\n    input.trim_start().to_ascii_lowercase().starts_with('y')\n}","tryCatchPattern":"match io::stdin().read_line(&mut need_instrut) {\n    Ok(0) => { /* skip instructions */ }\n    Ok(_) => { /* safe-index with starts_with */ }\n    Err(e) => { eprintln!(\"{}\", e); return; }\n}","preventionTips":["Never use raw slice indexing ([..1]) on user input — use starts_with or chars().next().","Handle EOF at the very first input prompt as a normal condition.","Guard all string indexing operations with length checks."],"tags":["rust","stdin","io","panic","expect","index-out-of-bounds","cli-game","stars"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}