{"record":{"id":"f44659b8fae432db","repo":"libnyanpasu/clash-nyanpasu","slug":"managed-target-is-not-replaceable","errorCode":null,"errorMessage":"managed target is not replaceable: {}","messagePattern":"managed target is not replaceable: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/service/profile_file.rs","lineNumber":725,"sourceCode":"            }\n            Ok(_) => bail!(\"managed target is not a file: {}\", path.display()),\n            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {\n                Ok(ABSENT_HASH.to_owned())\n            }\n            Err(error) => Err(error).with_context(|| format!(\"inspect {}\", path.display())),\n        }\n    }\n\n    fn ensure_replaceable_target(path: &Path) -> anyhow::Result<()> {\n        match std::fs::symlink_metadata(path) {\n            Ok(metadata) if metadata.file_type().is_symlink() || metadata.is_file() => Ok(()),\n            Ok(metadata) if is_symlink_or_reparse(&metadata) => {\n                bail!(\n                    \"managed target is an unsupported reparse point: {}\",\n                    path.display()\n                )\n            }\n            Ok(_) => bail!(\"managed target is not replaceable: {}\", path.display()),\n            Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),\n            Err(error) => Err(error).with_context(|| format!(\"inspect {}\", path.display())),\n        }\n    }\n\n    fn stage_resource(\n        root: &Path,\n        operation_id: &str,\n        resource: &MaterializationResource,\n    ) -> anyhow::Result<()> {\n        match resource {\n            MaterializationResource::File { content } => Self::write_private_file_new(\n                &Self::stage_file_path(root, operation_id),\n                content.as_bytes(),\n            ),\n            MaterializationResource::Symlink { target } => Self::write_private_file_new(\n                &Self::stage_link_path(root, operation_id),\n                target.as_str().as_bytes(),","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/service/profile_file.rs#L707-L743","documentation":"`ensure_replaceable_target` allows a managed path to be absent, a regular file, or a plain symlink before the materialization step replaces it. Any other entry type (a real directory, special file) cannot be replaced by the file/symlink write path, so the code fails with this error. It usually means a directory exists where a managed profile file/symlink should be.","triggerScenarios":"Materialization calls `ensure_replaceable_target` and the path exists as a non-file, non-symlink entry — typically a directory created by the user or another tool at the managed profile path (e.g. `.../profiles/config.yaml/`).","commonSituations":"User created a folder with the managed file's name; other applications/dotfile managers replaced files with directories; leftover state from a previous schema that used directories.","solutions":["Move or delete the directory at the reported path (`rm -r` / `Remove-Item -Recurse`) after preserving any needed contents","Re-run the profile materialization so the app creates the expected file/symlink","Configure other tooling not to place directories at this path","Verify the profile's managed path points to a file location"],"exampleFix":"// before: directory at managed path\n~/.config/nyanpasu/profiles/config.yaml/  (directory)\n// after\nmv ~/.config/nyanpasu/profiles/config.yaml ~/config.yaml.saved\n# re-run materialization; app recreates config.yaml as a file/symlink","handlingStrategy":"validation","validationCode":"fn path_is_replaceable(path: &std::path::Path) -> bool {\n    match std::fs::symlink_metadata(path) {\n        Ok(md) => md.is_file() || md.file_type().is_symlink(),\n        Err(e) => e.kind() == std::io::ErrorKind::NotFound,\n    }\n}\n// directories fail this pre-check","typeGuard":"fn replaceable(md: &std::fs::Metadata) -> bool {\n    md.is_file() || md.file_type().is_symlink()\n}","tryCatchPattern":"if let Err(e) = materialize_profile(...) {\n    if e.to_string().contains(\"not replaceable\") {\n        // a directory/other occupies the path: back up and remove it, then retry\n    } else { return Err(e); }\n}","preventionTips":["Do not create folders at paths the app materializes as files/symlinks","Check entry type before external tools write into managed locations","After restores or migrations, verify managed paths are files/symlinks","Delete stale directories at managed paths before re-running profile updates"],"tags":["filesystem","path-is-a-directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}