libnyanpasu/clash-nyanpasu · error
managed target is not replaceable: {}
Error message
managed target is not replaceable: {} What it means
`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.
Source
Thrown at backend/tauri/src/service/profile_file.rs:725
}
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(()),
Err(error) => Err(error).with_context(|| format!("inspect {}", path.display())),
}
}
fn stage_resource(
root: &Path,
operation_id: &str,
resource: &MaterializationResource,
) -> anyhow::Result<()> {
match resource {
MaterializationResource::File { content } => Self::write_private_file_new(
&Self::stage_file_path(root, operation_id),
content.as_bytes(),
),
MaterializationResource::Symlink { target } => Self::write_private_file_new(
&Self::stage_link_path(root, operation_id),
target.as_str().as_bytes(),View on GitHub (pinned to f7dbce2997)
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
Example fix
// before: directory at managed path ~/.config/nyanpasu/profiles/config.yaml/ (directory) // after mv ~/.config/nyanpasu/profiles/config.yaml ~/config.yaml.saved # re-run materialization; app recreates config.yaml as a file/symlink
Defensive patterns
Strategy: validation
Validate before calling
fn path_is_replaceable(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,
}
}
// directories fail this pre-check Type guard
fn replaceable(md: &std::fs::Metadata) -> bool {
md.is_file() || md.file_type().is_symlink()
} Try / catch
if let Err(e) = materialize_profile(...) {
if e.to_string().contains("not replaceable") {
// a directory/other occupies the path: back up and remove it, then retry
} else { return Err(e); }
} Prevention
- 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
When it happens
Trigger: 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/`).
Common situations: 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.
Related errors
- refusing to remove directory as a profile resource: {}
- managed target is not a file: {}
- failed to allocate a unique runtime candidate after 16 attem
- runtime candidate directory is a symlink or reparse point: {
- runtime candidate path is not a private directory: {path}
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/f44659b8fae432db.
Report an issue: GitHub.