sxyazi/yazi · error

Destination already exists

Error message

Destination already exists

What it means

bulk_rename refuses to overwrite: after computing the new URL, it checks maybe_exists(&new). If the destination already exists and must_identical does not confirm old and new are the same file, the pair fails with "Destination already exists". This prevents silent data loss from a rename collision.

Solutions

  1. Pick a unique destination name or add a suffix/number to avoid the collision.
  2. Delete or move the existing file at the destination first if the overwrite is intended.
  3. If the rename is intentional identity (same file), ensure old and new resolve to the same path so must_identical passes.

Example fix

// before
{ from: "a.txt", to: "b.txt" }  // b.txt exists
// after
{ from: "a.txt", to: "b-2.txt" }
Defensive patterns

Strategy: validation

Validate before calling

-- Lua, before bulk_rename
if Yo.fs_exists(new_url) then
  ya.notify({ title = "Rename", content = "Destination exists: " .. new_url, level = "warn" })
  return
end

Prevention

When it happens

Trigger: Renaming a file to a name that already exists in the same directory, where old and new are not the same inode.

Common situations: Regex/pattern rename producing a name that collides with another file; renaming a.txt to b.txt while b.txt exists; case-only renames on case-insensitive filesystems.

Related errors


AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-02). Data as JSON: /api/errors/38d8cd297064b543. Report an issue: GitHub.

Appendix: source

Thrown at yazi-actor/src/mgr/bulk_rename.rs:126

			return Ok(());
		}

		if !Self::ask_continue(&todo, decision)? {
			return Ok(());
		}

		let permit = WATCHER.acquire().await.unwrap();
		let (mut failed, mut succeeded) = (Vec::new(), HashMap::with_capacity(todo.len()));
		for (o, n) in todo {
			let (Ok(old), Ok(new)) =
				(Self::replace_url(&selected[o.0], root, &o), Self::replace_url(&selected[n.0], root, &n))
			else {
				failed.push((o, n, anyhow!("Invalid new or old file name")));
				continue;
			};

			if maybe_exists(&new).await && !engine::must_identical(&old, &new).await {
				failed.push((o, n, anyhow!("Destination already exists")));
			} else if let Err(e) = engine::rename(&old, &new).await {
				failed.push((o, n, e.into()));
			} else if let Ok(f) = engine::file(new).await {
				succeeded.insert(old, f);
			} else {
				failed.push((o, n, anyhow!("Failed to retrieve file info")));
			}
		}

		if !succeeded.is_empty() {
			let it = succeeded.iter().map(|(o, n)| (o.as_url(), n.url.as_url()));
			log_if_err!(Pubsub::pub_after_bulk_rename(it));
			FilesOp::rename(succeeded);
		}
		drop(permit);

		if !failed.is_empty() {
			Self::output_failed(failed).await?;

View on GitHub (pinned to 8ebf930f17)