{"id":"83946361b2230831","repo":"rust-lang/rust","slug":"failed-to-create-dst-e","errorCode":null,"errorMessage":"failed to create {dst:?}: {e}","messagePattern":"failed to create (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_cranelift/build_system/utils.rs","lineNumber":219,"sourceCode":"                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    }\n}\n\npub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {\n    for entry in fs::read_dir(from).unwrap() {\n        let entry = entry.unwrap();\n        let filename = entry.file_name();\n        if filename == \".\" || filename == \"..\" {\n            continue;\n        }\n        let src = from.join(&filename);\n        let dst = to.join(&filename);\n        if entry.metadata().unwrap().is_dir() {\n            fs::create_dir(&dst).unwrap_or_else(|e| panic!(\"failed to create {dst:?}: {e}\"));\n            copy_dir_recursively(&src, &dst);\n        } else {\n            fs::copy(&src, &dst).unwrap_or_else(|e| panic!(\"failed to copy {src:?}->{dst:?}: {e}\"));\n        }\n    }\n}\n\nstatic IN_GROUP: AtomicBool = AtomicBool::new(false);\npub(crate) struct LogGroup {\n    is_gha: bool,\n}\n\nimpl LogGroup {\n    pub(crate) fn guard(name: &str) -> LogGroup {\n        let is_gha = env::var(\"GITHUB_ACTIONS\").is_ok();\n\n        assert!(!IN_GROUP.swap(true, Ordering::SeqCst));\n        if is_gha {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_cranelift/build_system/utils.rs#L201-L237","documentation":"Panics inside copy_dir_recursively when fs::create_dir fails to create a destination directory while recursively copying a tree. cg_clif's build system uses this to stage the rustc source/library into a target directory (see prepare.rs:245,247). The panic is unrecoverable because the subsequent file copies depend on the directory existing.","triggerScenarios":"Invoked during `./y.rs prepare` (or the rustbuild bootstrap path) when copy_dir_recursively encounters a subdirectory entry whose destination path cannot be created. The error string interpolates the failing dst path and the underlying io::Error.","commonSituations":"Destination lives on a read-only mount or under a path the user lacks write permission for; the parent of dst was removed by a concurrent process; dst already exists as a non-directory file (e.g. a stray symlink or text file shadows a dir name); ENOSPC on the target volume; path-length limits on Windows.","solutions":["Confirm the destination root exists and is writable: `ls -ld <parent of dst>` and `touch <parent>/.write-probe`.","Remove a stale conflicting file/symlink at the dst path and re-run `./y.rs prepare`.","Free disk space on the target volume and re-run.","If reproducing in CI, ensure the working dir is cleaned between runs (the prepare step assumes an empty/overwritable target)."],"exampleFix":"// before\nfs::create_dir(&dst).unwrap_or_else(|e| panic!(\"failed to create {dst:?}: {e}\"));\n// after\nif let Err(e) = fs::create_dir(&dst) {\n    if e.kind() != io::ErrorKind::AlreadyExists {\n        panic!(\"failed to create {dst:?}: {e}\");\n    }\n}","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ensure_creatable(dst: &Path) -> Result<(), String> {\n    if dst.exists() {\n        return Ok(());\n    }\n    let parent = dst.parent().ok_or_else(|| format!(\"dst {:?} has no parent\", dst))?;\n    if !parent.exists() {\n        return Err(format!(\"parent dir {:?} does not exist; create it first\", parent));\n    }\n    let md = std::fs::metadata(parent).map_err(|e| format!(\"cannot stat parent {:?}: {}\", parent, e))?;\n    if md.permissions().readonly() {\n        return Err(format!(\"parent of {:?} is on a readonly filesystem\", dst));\n    }\n    if let Ok(s) = std::fs::statvfs(parent) {\n        if s.available_space() < 1024 {\n            return Err(format!(\"no free space on volume holding {:?}\", dst));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"use std::panic;\nlet res = panic::catch_unwind(|| fs::create_dir(dst));\nif res.is_err() { /* log, clean partial dst, propagate as io::Error */ }","preventionTips":["Pre-create destination parent directories with create_dir_all before invoking the build step.","Run the build with a working directory you own; avoid building into system paths or read-only mounts.","Ensure the user has write permission and the volume has free space before large codegen runs.","Treat any create-dir/create-file panic as fatal: cg_clif aborts, so validate paths up front rather than relying on recovery."],"tags":["build-system","filesystem","cg-clif","panic","io"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}