sxyazi/yazi · error · io::Error
restore target already exists: {to:?}
Error message
restore target already exists: {to:?} What it means
`restore_item` (yazi-fs/src/trash/common.rs:12) puts a trashed item back by first creating a placeholder at the destination (`create_dir` for folders, `File::create_new` for files) and then renaming the backing file over it. If the destination already exists, both the create and the rename are refused and the caller gets `ErrorKind::AlreadyExists` with `restore target already exists: {to:?}`. This prevents silently overwriting whatever now lives at the original path.
Source
Thrown at yazi-fs/src/trash/common.rs:12
#[cfg(trash_unix)]
pub(super) fn restore_item(from: &std::path::Path, to: &std::path::Path) -> std::io::Result<()> {
use std::{fs, io};
let is_dir = fs::symlink_metadata(from)?.is_dir();
if let Some(parent) = to.parent() {
fs::create_dir_all(parent)?;
}
match if is_dir { fs::create_dir(to) } else { fs::File::create_new(to).map(|_| ()) } {
Ok(()) => fs::rename(from, to),
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("restore target already exists: {to:?}"),
)),
Err(e) => Err(e),
}
}
View on GitHub (pinned to 94abcfa92f)
Solutions
- Move or delete the file currently at the destination path shown in the message, then restore again.
- Restore to a different location instead of the original (manually move the backing file out of `~/.local/share/Trash/files/`).
- If you own the workflow, catch `AlreadyExists` and prompt the user to rename/overwrite instead of failing the whole batch.
Example fix
// before
trash::restore(entries)?; // fails whole batch if one target exists
// after
for entry in entries {
if let Err(e) = restore_one(entry) {
if e.kind() == io::ErrorKind::AlreadyExists {
// skip and report, or restore under a new name
continue;
}
return Err(e);
}
} Defensive patterns
Strategy: validation
Validate before calling
let exists = if is_dir { to.is_dir() } else { to.exists() };
if exists {
// choose a new name or remove/move the occupant before restoring
} Try / catch
match restore_item(&from, &to) {
Ok(()) => {}
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
// skip or prompt: rename occupant, or restore under a suffixed name
}
Err(e) => return Err(e),
} Prevention
- Check `to.exists()` before restoring and resolve collisions explicitly (skip / rename / ask).
- Restore batches item-by-item so one collision cannot abort the rest.
- After recreating a file you previously trashed, expect the old trash copy to collide on restore.
When it happens
Trigger: Restoring a trash item whose original location has since been re-created: you trashed `report.pdf`, created a new file with the same name, then hit restore. Restoring two items to the same original path in one batch also triggers it.
Common situations: Trash restored long after deletion; a sync client (Dropbox/Nextcloud) recreated the path; duplicate items in the trash list with the same put-back path.
Related errors
- trash item has no put-back location
- trash item has no put-back location
- trash item has no put-back location
- Destination already exists
- Not a local URL: {url:?}
AI-assisted analysis of sxyazi/yazi@94abcfa92f (2026-08-16).
Data as JSON: /api/errors/4b67a0f2cbab9be4.
Report an issue: GitHub.