{"record":{"id":"dc5bb1db46e40537","repo":"jdx/mise","slug":"refusing-to-replace-non-directory-path","errorCode":null,"errorMessage":"refusing to replace non-directory path: {}","messagePattern":"refusing to replace non-directory path: (.+?)","errorType":"error_code","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":1603,"sourceCode":"    path: &Path,\n    owner: Option<&str>,\n    group: Option<&str>,\n    mode: u32,\n    replace: bool,\n) -> Result<()> {\n    match fs::symlink_metadata(path) {\n        Err(error)\n            if matches!(\n                error.kind(),\n                std::io::ErrorKind::NotFound | std::io::ErrorKind::NotADirectory\n            ) => {}\n        Err(error) => {\n            return Err(error)\n                .wrap_err_with(|| format!(\"failed to inspect directory {}\", path.display()));\n        }\n        Ok(metadata) if metadata.file_type().is_dir() => {}\n        Ok(_) if !replace => {\n            bail!(\"refusing to replace non-directory path: {}\", path.display())\n        }\n        Ok(_) => {\n            fs::remove_file(path).wrap_err_with(|| {\n                format!(\n                    \"failed to remove existing path before creating directory {}\",\n                    path.display()\n                )\n            })?;\n        }\n    }\n\n    #[cfg(unix)]\n    {\n        let directory = open_or_create_directory_tree(path)\n            .wrap_err_with(|| format!(\"failed to create directory {}\", path.display()))?;\n        set_directory_metadata(&directory, owner, group, mode)\n            .wrap_err_with(|| format!(\"failed to set metadata on directory {}\", path.display()))\n    }","sourceCodeStart":1585,"sourceCodeEnd":1621,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/managed_files.rs#L1585-L1621","documentation":"When creating a managed directory, the library stats the target path. If it exists as a non-directory (regular file, symlink to file, etc.) and `replace` was not requested, it refuses with this error rather than silently deleting a file to make room for a directory.","triggerScenarios":"Calling create managed directory with `replace: false` on a path occupied by a regular file — e.g. manifest defines directory \"/etc/app/conf.d\" but a stale file named \"conf.d\" exists.","commonSituations":"Path kind changed between tool versions or manifest edits; a file was accidentally created with the directory's name; leftover artifacts from a failed prior run.","solutions":["Set `replace: true` so the library removes the file before creating the directory","Delete the conflicting file manually and re-run","Fix the manifest path so it no longer collides with an existing file"],"exampleFix":"// before\ncreate_managed_dir(Path::new(\"/etc/app/conf.d\"), ReplaceMode::Keep)?; // a file exists there\n// after\ncreate_managed_dir(Path::new(\"/etc/app/conf.d\"), ReplaceMode::Replace)?;","handlingStrategy":"validation","validationCode":"fn check_dir_target(path: &std::path::Path, replace: bool) -> Result<(), String> {\n    match std::fs::metadata(path) {\n        Err(_) => Ok(()),\n        Ok(m) if m.is_dir() => Ok(()),\n        Ok(_) if replace => Ok(()),\n        Ok(_) => Err(format!(\"{} exists as a file; pass replace\", path.display())),\n    }\n}","typeGuard":"fn target_is_dir_or_absent(path: &std::path::Path) -> bool {\n    std::fs::metadata(path).map_or(true, |m| m.is_dir())\n}","tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"refusing to replace non-directory\") => {\n        std::fs::remove_file(path)?; // after verifying the file is expendable\n        retry_operation()?;\n    }\n    other => other?,\n}","preventionTips":["Remove stale files that share names with manifest directories","Verify path kinds after tool upgrades or manifest edits","Run a reconciliation pass before managed-directory creation"],"tags":["filesystem","path-conflict","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}