{"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":"error_code","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":740,"sourceCode":"            inspection: None,\n        })\n    }\n\n    pub(crate) fn plan(&self) -> Result<ResourcePlan> {\n        plan_directory(self).map(|plan| {\n            plan.with_origin(self.origin.clone())\n                .with_file_phase(self.phase)\n        })\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":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/managed_files.rs#L722-L758","documentation":"During planning of a managed file or directory, mise found the target path already exists but is not a directory (e.g. a regular file or symlink) while the declared state requires creating/managing it as a directory. Because replacing it would destroy existing content, mise refuses unless the config explicitly opts in with `replace = true`. This is a safety guard against clobbering unknown files at declared system paths.","triggerScenarios":"A [bootstrap.directories] entry (state present) whose path already exists on disk as a regular file or symlink, with `replace` unset/false; `plan()` returns ResourceAction::Unknown for the path and the bail fires in the directory-ensure path.","commonSituations":"A package or earlier setup step created a file where the config now declares a directory (e.g. /etc/foo moved from file to directory upstream); a stale symlink left by a previous tool; retargeting an existing path by mistake (typo in the directory path).","solutions":["If replacing the non-directory path is intended, set `replace = true` on the directory entry in [bootstrap.directories].","Verify the path is the one you intended — check for typos before allowing replacement.","Remove or relocate the conflicting file/symlink manually, or declare it in [bootstrap.files] with state = \"absent\" so mise cleans it up first.","If the path should stay a file, move the config entry from [bootstrap.directories] to [bootstrap.files]."],"exampleFix":"# before\n[bootstrap.directories.tmp-build]\npath = \"/var/lib/myapp/cache\"\n\n# after\n[bootstrap.directories.tmp-build]\npath = \"/var/lib/myapp/cache\"\nreplace = true\n","handlingStrategy":"validation","validationCode":"import os\ndef ensure_replace_safe(path: str, replace: bool):\n    if os.path.lexists(path) and not os.path.isdir(path) and not replace:\n        raise ValueError(f\"{path} exists and is not a directory; set replace = true or clean it up first\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Before declaring a directory, check the existing node type on target machines (ls -ld).","Set replace = true deliberately only for paths you own.","Declare stale conflicting files in [bootstrap.files] with state = \"absent\"."],"tags":["filesystem","safety-guard","bootstrap","config"],"backgroundTag":"file-already-exists","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"}