{"id":"88c27891036948b9","repo":"rust-lang/rust","slug":"failed-to-read-contents-of-path-err","errorCode":null,"errorMessage":"Failed to read contents of {path}: {err}","messagePattern":"Failed to read contents of (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_cranelift/build_system/utils.rs","lineNumber":188,"sourceCode":"#[track_caller]\npub(crate) fn spawn_and_wait(mut cmd: Command) {\n    let status = cmd.spawn().unwrap().wait().unwrap();\n    if !status.success() {\n        eprintln!(\"{cmd:?} exited with status {:?}\", status);\n        process::exit(1);\n    }\n}\n\n/// Create the specified directory if it doesn't exist yet and delete all contents.\npub(crate) fn ensure_empty_dir(path: &Path) {\n    fs::create_dir_all(path).unwrap();\n    let read_dir = match fs::read_dir(path) {\n        Ok(read_dir) => read_dir,\n        Err(err) if err.kind() == io::ErrorKind::NotFound => {\n            return;\n        }\n        Err(err) => {\n            panic!(\"Failed to read contents of {path}: {err}\", path = path.display())\n        }\n    };\n    for entry in read_dir {\n        let entry = entry.unwrap();\n        if entry.file_type().unwrap().is_dir() {\n            match fs::remove_dir_all(entry.path()) {\n                Ok(()) => {}\n                Err(err) if err.kind() == io::ErrorKind::NotFound => {}\n                Err(err) => panic!(\"Failed to remove {path}: {err}\", path = entry.path().display()),\n            }\n        } else {\n            match fs::remove_file(entry.path()) {\n                Ok(()) => {}\n                Err(err) if err.kind() == io::ErrorKind::NotFound => {}\n                Err(err) => panic!(\"Failed to remove {path}: {err}\", path = entry.path().display()),\n            }\n        }\n    }","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_cranelift/build_system/utils.rs#L170-L206","documentation":"This `panic!` fires inside `ensure_empty_dir` (utils.rs:180) when `fs::read_dir(path)` returns an error other than `NotFound`. `NotFound` is tolerated (nothing to clear), but failures such as `PermissionDenied`, a broken symlink, or an unreadable directory abort the cranelift build-system immediately. The path (already `create_dir_all`'d on the line above) and the OS error are formatted into the message.","triggerScenarios":"Triggered when the cranelift build calls `ensure_empty_dir(target_dir)` (or any other path managed by `utils.rs`) and `read_dir` at line 182 returns an I/O error other than `NotFound`. Because `create_dir_all` succeeded one line earlier, this usually means the dir was created but is unreadable (mode bits, ACL, SELinux label, or a dangling symlink somewhere under it).","commonSituations":"Surfaces in CI or local cranelift builds when the target/download dir was created by a different user (e.g. an earlier `sudo ./y.sh`), when SELinux/AppArmor deny directory reads, or when the dir lives on a filesystem (FUSE, network) that fails `read_dir` transiently. Also seen after a crashed build leaves the tree in a half-state.","solutions":["Read the `err` field: `PermissionDenied` ⇒ `sudo chown -R $USER:$USER <path>` or `chmod -R u+rX <path>`.","Manually wipe and recreate the path printed in the panic: `rm -rf <path> && mkdir -p <path>`, then re-run the build.","Check for SELinux/AppArmor denials (`ausearch -m avc` / `dmesg`) and label the build tree accordingly.","Move the build dir off network/FUSE filesystems onto a local ext4/xfs volume.","Re-run from a clean slate: `./y.sh clean && ./y.sh prepare`."],"exampleFix":"# before — ensure_empty_dir panics with PermissionDenied\n./y.sh prepare\n# panics: Failed to read contents of /path/dir: Permission denied\n\n# after — fix perms then re-run\nsudo chown -R $USER:$USER /path/dir\nchmod -R u+rX /path/dir\n./y.sh prepare","handlingStrategy":"validation","validationCode":"// utils.rs read failure — the build tried to read a path that is missing,\n// unreadable, or wrong. Validate existence + readability BEFORE invoking:\nuse std::path::Path;\nfn readable(p: &Path) -> std::io::Result<()> {\n    let md = std::fs::metadata(p)?;\n    if md.is_dir() { return Err(std::io::Error::new(std::io::ErrorKind::IsADirectory, \"is dir\")); }\n    if md.permissions().readonly() { /* still readable, ok */ }\n    std::fs::read(p).map(|_| ()) // prove we can actually read the bytes\n}\n// Call readable(&path)? before the build step that consumes it.","typeGuard":null,"tryCatchPattern":"// Read defensively in your own driver, surfacing the exact cause:\nfn read_or_diag(p: &std::path::Path) -> Vec<u8> {\n    match std::fs::read(p) {\n        Ok(b) => b,\n        Err(e) => {\n            eprintln!(\"read failed: {:?} kind={:?} exists={}\",\n                p, e.kind(), p.exists());\n            std::process::exit(1);\n        }\n    }\n}","preventionTips":["Verify the input path exists and is readable before the build step that needs it","Do not move, delete, or overwrite build inputs while a build is running","Pin absolute paths; relative paths break when the build changes its working dir","On network shares, copy inputs locally first to avoid mid-read dropouts"],"tags":["rustc","cranelift","build-system","io","filesystem"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}