sxyazi/yazi · error · io::Error

NotFound

NotFound

Error message

trash item has no put-back location

What it means

Trash::restore moves each trashed item back to its recorded original location. If the entry's .DS_Store-derived put-back location is missing (original is None), the item cannot be restored and this NotFound error is returned.

Source

Thrown at yazi-fs/src/trash/macos/trash.rs:102

		let changed = !latest.cha.hits(current.cha)
			|| latest.extra.link_to() != current.extra.link_to()
			|| latest.extra.backing() != current.extra.backing();

		Ok(changed.then_some(latest))
	}

	pub(crate) fn remove_file(&self, entry: &TrashEntry) -> io::Result<()> {
		fs::remove_file(&entry.backing)
	}

	pub(crate) fn remove_dir(&self, entry: &TrashEntry) -> io::Result<()> {
		fs::remove_dir(&entry.backing)
	}

	pub(crate) fn restore(&self, entries: TrashEntries) -> io::Result<()> {
		for entry in entries {
			let to = entry.original.as_ref().ok_or_else(|| {
				io::Error::new(io::ErrorKind::NotFound, "trash item has no put-back location")
			})?;

			restore_item(&entry.backing, &to)?;
		}
		Ok(())
	}

	pub(crate) fn rename(&self, entry: &TrashEntry, path: &Path) -> io::Result<()> {
		fs::rename(&entry.backing, path)
	}

	pub(crate) fn empty(&self) -> io::Result<()> {
		let root = self.root()?;
		for dent in ok_or_not_found!(fs::read_dir(root), return Ok(())) {
			let dent = dent?;
			if dent.file_type()?.is_dir() {
				fs::remove_dir_all(dent.path())?;
			} else {

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Ensure the trash .DS_Store contains valid put-back records for the item
  2. Restore manually with mv to the desired path and update records
  3. Filter entries with original == None before restoring and report them separately

Example fix

// before
trash.restore(entries)?;
// after
let (restorable, missing): (Vec<_>, Vec<_>) = entries.into_iter().partition(|e| e.original.is_some());
if !missing.is_empty() { eprintln!("cannot restore {} items", missing.len()); }
trash.restore(restorable.into())?;
Defensive patterns

Strategy: validation

Validate before calling

let restorable: Vec<_> = entries.iter().filter(|e| e.original.is_some()).collect();
if restorable.len() != entries.len() { warn_about_missing_putback(); }

Type guard

fn has_putback(entry: &TrashEntry) -> bool { entry.original.is_some() }

Try / catch

match trash.restore(entries) {
    Err(e) if e.kind() == io::ErrorKind::NotFound => prompt_manual_restore(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling Trash::restore with a TrashEntries list containing an entry whose `original` field is None — typically because the trash's .DS_Store lacked/failed to parse the put-back record for that item.

Common situations: .DS_Store deleted or unreadable, item trashed by a tool that doesn't write put-back metadata, DsStore::parse fell back to default via unwrap_or_default.

Understand the failure class

Background: "Not Found" / HTTP 404 Errors: What They Mean and How to Fix Them Across Libraries — this error's family across 6 libraries.

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/9178e03c2256bf91. Report an issue: GitHub.