{"record":{"id":"c66934c2503cb73c","repo":"jdx/mise","slug":"refusing-to-replace-non-directory-path-set-rep","errorCode":null,"errorMessage":"refusing to replace non-directory path {}; set replace = true to allow replacement","messagePattern":"refusing to replace non-directory path (.+?); set replace = true to allow replacement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":672,"sourceCode":"            replace: config.replace,\n            notify: config.notify,\n            origin,\n            inspection: None,\n        })\n    }\n\n    pub(crate) fn plan(&self) -> Result<ResourcePlan> {\n        plan_directory(self).map(|plan| plan.with_origin(self.origin.clone()))\n    }\n\n    fn operation(&self) -> Result<Option<PrivilegedAction>> {\n        match self.plan()?.action {\n            ResourceAction::Noop => return Ok(None),\n            ResourceAction::Unknown if self.state == ManagedState::Absent => bail!(\n                \"refusing to remove non-directory path {} as a directory; declare it in [bootstrap.files]\",\n                self.path.display()\n            ),\n            ResourceAction::Unknown => bail!(\n                \"refusing to replace non-directory path {}; set replace = true to allow replacement\",\n                self.path.display()\n            ),\n            _ => {}\n        }\n        Ok(Some(match self.state {\n            ManagedState::Present => PrivilegedAction::CreateDirectory {\n                path: self.path.clone(),\n                owner: self.owner.clone(),\n                group: self.group.clone(),\n                mode: self.mode,\n                replace: self.replace,\n            },\n            ManagedState::Absent => PrivilegedAction::RemoveDirectory {\n                path: self.path.clone(),\n                recursive: self.recursive,\n            },\n        }))","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/managed_files.rs#L654-L690","documentation":"Raised in ManagedDirectoryRequest::operation when a directory entry (any state) is planned and inspection returns ResourceAction::Unknown because the path exists as a non-directory (regular file, socket, etc.), and the entry does not opt in with replace = true. The library refuses to silently clobber non-directory filesystem objects to create a directory.","triggerScenarios":"Converging a [bootstrap.directories] entry (typically state = \"present\") whose path exists as a non-directory on disk and `replace` is false/unset — the (ResourceAction::Unknown, non-Absent) arm.","commonSituations":"A package upgrade replaced a directory with a file; a stale plain file blocks a path the config wants as a directory; managing /etc paths where another tool left a file behind.","solutions":["Set replace = true on the directory entry to allow the library to remove the non-directory and create the directory.","Check what the path actually is (ls -la) and manage it correctly via [bootstrap.files] instead if it should remain a file.","Remove the blocking file manually, then re-run bootstrap.","Pick a different path if the collision is unintentional."],"exampleFix":"# before\n[[bootstrap.directories]]\npath = \"/etc/myapp/conf.d\"\nstate = \"present\"\n\n# after\n[[bootstrap.directories]]\npath = \"/etc/myapp/conf.d\"\nstate = \"present\"\nreplace = true","handlingStrategy":"validation","validationCode":"for path in &managed_dir_paths {\n    if let Ok(meta) = std::fs::metadata(path) {\n        if !meta.is_dir() && !replace_enabled(path) {\n            eprintln!(\"{} is not a directory; set replace = true or fix the entry\", path.display());\n        }\n    }\n}","typeGuard":"fn is_directory_or_missing(path: &std::path::Path) -> bool {\n    match std::fs::metadata(path) {\n        Ok(m) => m.is_dir(),\n        Err(_) => true,\n    }\n}","tryCatchPattern":null,"preventionTips":["Use replace = true only after confirming removal of the blocking file is intended.","Check for stale files at directory paths before converging new hosts.","Coordinate with tools/packages that may convert directories into files."],"tags":["filesystem","bootstrap","safety","destructive-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}