{"record":{"id":"89c566176dee6dad","repo":"a-b-street/abstreet","slug":"couldn-t-read-dir","errorCode":null,"errorMessage":"Couldn't read_dir {:?}: {}","messagePattern":"Couldn't read_dir (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"abstio/src/io_native.rs","lineNumber":31,"sourceCode":"use abstutil::{elapsed_seconds, prettyprint_usize, to_json, Timer, PROGRESS_FREQUENCY_SECONDS};\n\npub use crate::io::*;\n\npub fn file_exists<I: AsRef<str>>(path: I) -> bool {\n    Path::new(path.as_ref()).exists()\n}\n\n/// Returns full paths\npub fn list_dir(path: String) -> Vec<String> {\n    let mut files: Vec<String> = Vec::new();\n    match fs_err::read_dir(&path) {\n        Ok(iter) => {\n            for entry in iter {\n                files.push(entry.unwrap().path().to_str().unwrap().to_string());\n            }\n        }\n        Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => {}\n        Err(e) => panic!(\"Couldn't read_dir {:?}: {}\", path, e),\n    };\n    files.sort();\n    files\n}\n\npub fn slurp_file<I: AsRef<str>>(path: I) -> Result<Vec<u8>> {\n    inner_slurp_file(path.as_ref())\n}\nfn inner_slurp_file(path: &str) -> Result<Vec<u8>> {\n    || -> Result<Vec<u8>> {\n        let mut file = File::open(path)?;\n        let mut buffer = Vec::new();\n        file.read_to_end(&mut buffer)?;\n        Ok(buffer)\n    }()\n    .with_context(|| path.to_string())\n}\n","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/abstio/src/io_native.rs#L13-L49","documentation":"list_dir reads a directory and returns sorted full paths; it silently treats a missing directory as empty (NotFound), but any other read_dir failure panics with this message. Such errors mean the path exists but can't be read: permission problems, the path is a file not a directory, or an OS-level I/O error.","triggerScenarios":"Calling list_dir(path) where the path is a regular file rather than a directory; the process lacks read permission on the directory; an OS I/O error occurs while iterating entries; also entry.unwrap() inside the loop panics on a bad directory entry (e.g. invalid UTF-8 path).","commonSituations":"Passing a file path where a directory was expected; sandboxed/containerized environments without permission on the data directory; scanning directories with entries whose names aren't valid UTF-8; NFS/network mounts returning transient I/O errors.","solutions":["Check the path is a directory (Path::is_dir) and readable before calling list_dir.","Fix permissions on the directory (chmod/chown) or run with appropriate access.","If a NotFound should be tolerated, note list_dir already returns an empty Vec for that case; handle other Err kinds by pre-checking the path.","Reproduce the underlying io::Error from the panic message and address it (e.g. replace the file-vs-directory path, remount a failed volume)."],"exampleFix":"// before\nlet files = abstio::list_dir(\"data/input\".to_string());\n\n// after\nlet dir = std::path::Path::new(\"data/input\");\nlet files = if dir.is_dir() {\n    abstio::list_dir(dir.to_str().unwrap().to_string())\n} else {\n    eprintln!(\"data/input is not a readable directory\");\n    Vec::new()\n};","handlingStrategy":"validation","validationCode":"let dir = std::path::Path::new(&path);\nif !dir.is_dir() {\n    eprintln!(\"{:?} is not a directory (list_dir only tolerates NotFound)\", dir);\n}\nif !dir.is_dir() || std::fs::read_dir(dir).is_err() {\n    eprintln!(\"{:?} is not readable\", dir);\n}","typeGuard":"fn is_readable_dir(path: &str) -> bool {\n    let p = std::path::Path::new(path);\n    p.is_dir() && std::fs::read_dir(p).is_ok()\n}","tryCatchPattern":"if !is_readable_dir(&dir_path) {\n    eprintln!(\"{:?} is not a readable directory\", dir_path);\n    return Vec::new();\n}\nlet files = abstio::list_dir(dir_path);","preventionTips":["Remember NotFound is tolerated (empty Vec) but every other error panics; pre-check is_dir for file-vs-directory mistakes.","Check directory read permissions in container/sandbox setups before runs.","Avoid scanning directories that may contain non-UTF-8 entry names (entry.unwrap() inside list_dir panics).","Guard against network mounts going away mid-run; copy data locally when possible."],"tags":["rust","panic","filesystem","directory"],"backgroundTag":"directory-not-found","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}