{"record":{"id":"93904b034b1099f3","repo":"libnyanpasu/clash-nyanpasu","slug":"managed-target-is-not-a-file","errorCode":null,"errorMessage":"managed target is not a file: {}","messagePattern":"managed target is not a file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/service/profile_file.rs","lineNumber":708,"sourceCode":"                let target = std::fs::read_link(path)\n                    .with_context(|| format!(\"read managed symlink {}\", path.display()))?;\n                let target = target\n                    .to_str()\n                    .context(\"managed symlink target is not valid UTF-8\")?;\n                Ok(hash_tagged(b\"symlink\", target.as_bytes()))\n            }\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(metadata) if metadata.is_file() => {\n                let content = std::fs::read(path)\n                    .with_context(|| format!(\"read managed profile {}\", path.display()))?;\n                Ok(hash_tagged(b\"file\", &content))\n            }\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(()),","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/service/profile_file.rs#L690-L726","documentation":"`path_hash` only knows how to hash regular files and symlinks (and treat absence as a sentinel hash). Any other entry type — a real directory, device node, FIFO, etc. — cannot be fingerprinted, so the function fails with this error. It indicates the managed profile path expected to be a file or symlink is actually something else, usually a directory.","triggerScenarios":"Drift verification calls `path_hash` on a managed path that `symlink_metadata` reports as a non-file, non-symlink entry (most commonly a directory). E.g. user replaced a managed profile file with a same-named folder.","commonSituations":"User created a directory where the app materializes a profile file; package managers or other tools installing directories at the same path; leftover state from a different app version that used directories.","solutions":["Check the reported path; if it's an unexpected directory, move/backup its contents and remove it so the app can create the managed file/symlink","Re-run profile materialization to recreate the expected file","Adjust conflicting tooling (dotfile managers, other apps) that write directories to this path","Verify you are pointing the profile at the intended file path, not a directory path"],"exampleFix":"// before: managed path is a directory\n~/.config/clash/config.yaml/  (directory)\n// after\nmv ~/.config/clash/config.yaml ~/config.yaml.dir-backup\n# re-run materialization; app recreates config.yaml as a file","handlingStrategy":"validation","validationCode":"fn managed_target_shape_ok(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// run before drift-check/materialization; a real directory fails this check","typeGuard":"fn is_file_or_symlink(md: &std::fs::Metadata) -> bool {\n    md.is_file() || md.file_type().is_symlink()\n}","tryCatchPattern":"match path_hash(&managed) {\n    Err(e) if e.to_string().contains(\"not a file\") => {\n        // path is a directory/other: back up and remove it, then re-run materialization\n    }\n    other => other?,\n}","preventionTips":["Keep managed profile paths pointing at files, never directories","Check for directory name collisions before installing other tools into the same location","After schema/version migrations, verify entry types at managed paths","Let the app create managed paths; do not pre-create them as folders"],"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"}