{"record":{"id":"a495fe038e06a801","repo":"XAMPPRocky/tokei","slug":"couldn-t-read-file","errorCode":null,"errorMessage":"Couldn't read file","messagePattern":"Couldn't read file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/input.rs","lineNumber":176,"sourceCode":"    (json, \"json\", Json [serde_json]) =>\n        serde_json::from_str,\n        serde_json::to_string,\n\n    (yaml, \"yaml\", Yaml [serde_yaml]) =>\n        serde_yaml::from_str,\n        serde_yaml::to_string,\n);\n\npub fn add_input(input: &str, languages: &mut Languages) -> bool {\n    use std::fs::File;\n    use std::io::Read;\n\n    let map = match File::open(input) {\n        Ok(mut file) => {\n            let contents = {\n                let mut contents = String::new();\n                file.read_to_string(&mut contents)\n                    .expect(\"Couldn't read file\");\n                contents\n            };\n\n            convert_input(&contents)\n        }\n        Err(_) => {\n            if input == \"stdin\" {\n                let mut stdin = ::std::io::stdin();\n                let mut buffer = String::new();\n\n                let _ = stdin.read_to_string(&mut buffer);\n                convert_input(&buffer)\n            } else {\n                convert_input(input)\n            }\n        }\n    };\n","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/XAMPPRocky/tokei/blob/fa44e5194060305576514d59b850353643afbfc8/src/input.rs#L158-L194","documentation":"This panic comes from an `.expect(\"Couldn't read file\")` on `file.read_to_string()` inside `add_input` (src/input.rs:176). The file was successfully *opened* via `File::open`, but reading its bytes into a `String` failed. By far the most common cause is `InvalidData`: the file contains bytes that are not valid UTF-8, since `read_to_string` requires valid UTF-8. Other I/O errors (device errors, permission changes mid-read) can also trigger it.","triggerScenarios":"Calling `add_input(path)` (e.g. via the CLI's input argument) on a file that opens successfully but whose contents are not valid UTF-8 — e.g. a binary file, a Latin-1/UTF-16 encoded file, or a file with a BOM-less non-UTF-8 encoding. `File::open` succeeds (existence/permissions are fine) so the `Err(_)` fallback that treats the input as inline text is skipped, and the subsequent `read_to_string` panics.","commonSituations":"Passing a binary blob or compiled artifact as an input file; counting a project whose source files are saved in a legacy encoding (Windows-1252, Shift-JIS, UTF-16); a broken symlink resolving to a special file; reading from /proc or a device file where open succeeds but read fails.","solutions":["Re-encode or fix the input file as valid UTF-8 (e.g. `iconv -f WINDOWS-1252 -t UTF-8 in.txt > out.txt`) and retry","Verify the path points to a regular UTF-8 text file, not a binary/special file, before invoking the tool","Replace the `.expect` with graceful handling: match on the `io::Error` kind (`ErrorKind::InvalidData`) and fall back to reading bytes with `String::from_utf8_lossy` or skip the file with a warning","If input may be binary, open with `File::open` + `read_to_end` into `Vec<u8>` and convert with `String::from_utf8_lossy` instead of `read_to_string`"],"exampleFix":"// before\nfile.read_to_string(&mut contents)\n    .expect(\"Couldn't read file\");\n// after\nif let Err(e) = file.read_to_string(&mut contents) {\n    if e.kind() == std::io::ErrorKind::InvalidData {\n        eprintln!(\"{} is not valid UTF-8; skipping\", input);\n        return false;\n    }\n    panic!(\"Couldn't read file: {}\", e);\n}","handlingStrategy":"try-catch","validationCode":"fn is_valid_utf8_file(path: &str) -> bool {\n    use std::fs::File;\n    use std::io::Read;\n    let mut f = match File::open(path) { Ok(f) => f, Err(_) => return false };\n    let mut buf = Vec::new();\n    if f.read_to_end(&mut buf).is_err() { return false; }\n    String::from_utf8(buf).is_ok()\n}\n// call before: if !is_valid_utf8_file(input) { /* skip or convert */ }","typeGuard":"fn is_text_file(path: &str) -> bool {\n    std::fs::metadata(path).map(|m| m.is_file()).unwrap_or(false)\n        && is_valid_utf8_file(path)\n}","tryCatchPattern":"match file.read_to_string(&mut contents) {\n    Ok(_) => { /* proceed with contents */ }\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        eprintln!(\"Input is not valid UTF-8: {}\", e);\n        // fall back: read bytes and String::from_utf8_lossy\n    }\n    Err(e) => { eprintln!(\"Couldn't read file: {}\", e); return false; }\n}","preventionTips":["Verify inputs are UTF-8 text before passing them (run `file` or `iconv -f UTF-8 -t UTF-8` as a sanity check)","Avoid pointing the tool at binary artifacts, images, or special/device files","Normalize legacy encodings to UTF-8 in a preprocessing step","In library code, prefer returning `io::Result` over `.expect`/`.unwrap` on reads so callers can handle encoding failures"],"tags":["rust","file-io","utf-8","panic"],"backgroundTag":"file-read-failed","analyzedSha":"fa44e5194060305576514d59b850353643afbfc8","analyzedAt":"2026-09-06T07:54:23.092Z","contentChangedAt":"2026-09-06T07:54:23.092Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}