{"record":{"id":"38d8cd297064b543","repo":"sxyazi/yazi","slug":"destination-already-exists","errorCode":null,"errorMessage":"Destination already exists","messagePattern":"Destination already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-actor/src/mgr/bulk_rename.rs","lineNumber":126,"sourceCode":"\t\t\treturn Ok(());\n\t\t}\n\n\t\tif !Self::ask_continue(&todo, decision)? {\n\t\t\treturn Ok(());\n\t\t}\n\n\t\tlet permit = WATCHER.acquire().await.unwrap();\n\t\tlet (mut failed, mut succeeded) = (Vec::new(), HashMap::with_capacity(todo.len()));\n\t\tfor (o, n) in todo {\n\t\t\tlet (Ok(old), Ok(new)) =\n\t\t\t\t(Self::replace_url(&selected[o.0], root, &o), Self::replace_url(&selected[n.0], root, &n))\n\t\t\telse {\n\t\t\t\tfailed.push((o, n, anyhow!(\"Invalid new or old file name\")));\n\t\t\t\tcontinue;\n\t\t\t};\n\n\t\t\tif maybe_exists(&new).await && !engine::must_identical(&old, &new).await {\n\t\t\t\tfailed.push((o, n, anyhow!(\"Destination already exists\")));\n\t\t\t} else if let Err(e) = engine::rename(&old, &new).await {\n\t\t\t\tfailed.push((o, n, e.into()));\n\t\t\t} else if let Ok(f) = engine::file(new).await {\n\t\t\t\tsucceeded.insert(old, f);\n\t\t\t} else {\n\t\t\t\tfailed.push((o, n, anyhow!(\"Failed to retrieve file info\")));\n\t\t\t}\n\t\t}\n\n\t\tif !succeeded.is_empty() {\n\t\t\tlet it = succeeded.iter().map(|(o, n)| (o.as_url(), n.url.as_url()));\n\t\t\tlog_if_err!(Pubsub::pub_after_bulk_rename(it));\n\t\t\tFilesOp::rename(succeeded);\n\t\t}\n\t\tdrop(permit);\n\n\t\tif !failed.is_empty() {\n\t\t\tSelf::output_failed(failed).await?;","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-actor/src/mgr/bulk_rename.rs#L108-L144","documentation":"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.","triggerScenarios":"Renaming a file to a name that already exists in the same directory, where old and new are not the same inode.","commonSituations":"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.","solutions":["Pick a unique destination name or add a suffix/number to avoid the collision.","Delete or move the existing file at the destination first if the overwrite is intended.","If the rename is intentional identity (same file), ensure old and new resolve to the same path so must_identical passes."],"exampleFix":"// before\n{ from: \"a.txt\", to: \"b.txt\" }  // b.txt exists\n// after\n{ from: \"a.txt\", to: \"b-2.txt\" }","handlingStrategy":"validation","validationCode":"-- Lua, before bulk_rename\nif Yo.fs_exists(new_url) then\n  ya.notify({ title = \"Rename\", content = \"Destination exists: \" .. new_url, level = \"warn\" })\n  return\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate unique names (append -1, -2, ...) when collisions are possible.","Preview the rename mapping and highlight collisions before executing.","Watch for case-only collisions on case-insensitive filesystems."],"tags":["rename","collision","filesystem"],"backgroundTag":"destination-already-exists","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}