libnyanpasu/clash-nyanpasu · error

managed target is not a file: {}

Error message

managed target is not a file: {}

What it means

`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.

Source

Thrown at backend/tauri/src/service/profile_file.rs:708

                let target = std::fs::read_link(path)
                    .with_context(|| format!("read managed symlink {}", path.display()))?;
                let target = target
                    .to_str()
                    .context("managed symlink target is not valid UTF-8")?;
                Ok(hash_tagged(b"symlink", target.as_bytes()))
            }
            Ok(metadata) if is_symlink_or_reparse(&metadata) => {
                bail!(
                    "managed target is an unsupported reparse point: {}",
                    path.display()
                )
            }
            Ok(metadata) if metadata.is_file() => {
                let content = std::fs::read(path)
                    .with_context(|| format!("read managed profile {}", path.display()))?;
                Ok(hash_tagged(b"file", &content))
            }
            Ok(_) => bail!("managed target is not a file: {}", path.display()),
            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
                Ok(ABSENT_HASH.to_owned())
            }
            Err(error) => Err(error).with_context(|| format!("inspect {}", path.display())),
        }
    }

    fn ensure_replaceable_target(path: &Path) -> anyhow::Result<()> {
        match std::fs::symlink_metadata(path) {
            Ok(metadata) if metadata.file_type().is_symlink() || metadata.is_file() => Ok(()),
            Ok(metadata) if is_symlink_or_reparse(&metadata) => {
                bail!(
                    "managed target is an unsupported reparse point: {}",
                    path.display()
                )
            }
            Ok(_) => bail!("managed target is not replaceable: {}", path.display()),
            Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),

View on GitHub (pinned to f7dbce2997)

Solutions

  1. 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
  2. Re-run profile materialization to recreate the expected file
  3. Adjust conflicting tooling (dotfile managers, other apps) that write directories to this path
  4. Verify you are pointing the profile at the intended file path, not a directory path

Example fix

// before: managed path is a directory
~/.config/clash/config.yaml/  (directory)
// after
mv ~/.config/clash/config.yaml ~/config.yaml.dir-backup
# re-run materialization; app recreates config.yaml as a file
Defensive patterns

Strategy: validation

Validate before calling

fn managed_target_shape_ok(path: &std::path::Path) -> bool {
    match std::fs::symlink_metadata(path) {
        Ok(md) => md.is_file() || md.file_type().is_symlink(),
        Err(e) => e.kind() == std::io::ErrorKind::NotFound,
    }
}
// run before drift-check/materialization; a real directory fails this check

Type guard

fn is_file_or_symlink(md: &std::fs::Metadata) -> bool {
    md.is_file() || md.file_type().is_symlink()
}

Try / catch

match path_hash(&managed) {
    Err(e) if e.to_string().contains("not a file") => {
        // path is a directory/other: back up and remove it, then re-run materialization
    }
    other => other?,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/93904b034b1099f3. Report an issue: GitHub.