{"record":{"id":"6991963a7e0213ba","repo":"jdx/mise","slug":"refusing-to-replace-non-file-path-set-replace","errorCode":null,"errorMessage":"refusing to replace non-file path {}; set replace = true to allow replacement","messagePattern":"refusing to replace non-file path (.+?); set replace = true to allow replacement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/managed_files.rs","lineNumber":600,"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_file(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 directory {} as a file; declare it in [bootstrap.directories]\",\n                self.path.display()\n            ),\n            ResourceAction::Unknown => bail!(\n                \"refusing to replace non-file path {}; set replace = true to allow replacement\",\n                self.path.display()\n            ),\n            _ => {}\n        }\n        Ok(Some(match self.state {\n            ManagedState::Present => PrivilegedAction::WriteFile {\n                path: self.path.clone(),\n                content: self.content.clone().expect(\"present file has content\"),\n                owner: self.owner.clone(),\n                group: self.group.clone(),\n                mode: self.mode,\n                replace: self.replace,\n            },\n            ManagedState::Absent => PrivilegedAction::RemoveFile {\n                path: self.path.clone(),\n            },\n        }))","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/managed_files.rs#L582-L618","documentation":"Raised in ManagedFileRequest::operation when a file entry (any state) is planned and inspection returns ResourceAction::Unknown because the path exists as something other than a regular file (directory, socket, etc.), and the entry does not opt in with replace = true. The library refuses to clobber non-file filesystem objects silently.","triggerScenarios":"Converging a [bootstrap.files] entry (state = \"present\" or \"absent\"; for absent-and-directory see the sibling error) whose path exists as a non-regular-file and `replace` is false/unset — the (ResourceAction::Unknown, non-Absent) arm.","commonSituations":"A service created a directory or socket at the path the config wants to own; a symlink was replaced by a real directory; managing a path like /var/run/myapp that a daemon recreates as a directory on every start.","solutions":["Set replace = true on the file entry to explicitly allow the library to remove and replace the non-file path.","Verify the path is expected to be a non-file; if it should stay a directory, manage it via [bootstrap.directories] instead.","Choose a different target path that does not collide with the daemon-created object.","Stop whatever process recreates the object at that path before converging."],"exampleFix":"# before\n[[bootstrap.files]]\npath = \"/var/run/myapp/sock.conf\"\ncontent = \"...\"\nstate = \"present\"\n\n# after\n[[bootstrap.files]]\npath = \"/var/run/myapp/sock.conf\"\ncontent = \"...\"\nstate = \"present\"\nreplace = true","handlingStrategy":"validation","validationCode":"for path in &managed_file_paths {\n    if let Ok(meta) = std::fs::symlink_metadata(path) {\n        if !meta.is_file() && !replace_enabled(path) {\n            eprintln!(\"{} is not a regular file; set replace = true or fix the entry\", path.display());\n        }\n    }\n}","typeGuard":"fn is_regular_file(path: &std::path::Path) -> bool {\n    std::fs::metadata(path).map(|m| m.is_file()).unwrap_or(true)\n}","tryCatchPattern":null,"preventionTips":["Set replace = true deliberately on entries that may collide with daemon-created objects.","Avoid managing runtime paths (sockets, /var/run) that services recreate as directories.","Stat target paths before converging to detect non-file occupants early."],"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"}