{"record":{"id":"a926b063b74722b0","repo":"sxyazi/yazi","slug":"invalid-new-or-old-file-name","errorCode":null,"errorMessage":"Invalid new or old file name","messagePattern":"Invalid new or old file name","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"yazi-actor/src/mgr/bulk_rename.rs","lineNumber":121,"sourceCode":"\t\t}\n\n\t\tlet (old, new) = old.into_iter().zip(new).filter(|(o, n)| o != n).unzip();\n\t\tlet todo = Self::prioritized_paths(old, new);\n\t\tif todo.is_empty() {\n\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);","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/sxyazi/yazi/blob/94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2/yazi-actor/src/mgr/bulk_rename.rs#L103-L139","documentation":"In bulk rename, each old/new pair is rebuilt into a full URL via replace_url, which does url.try_replace(take, PathDyn::with(url.kind(), rep)). If the edited name from the temp file cannot be turned into a valid dynamic path for that entry's URL kind, the pair is pushed to failed with \"Invalid new or old file name\" and skipped; the rest of the batch proceeds.","triggerScenarios":"A line in the bulk-rename temp file is empty, contains NUL or bytes invalid for the entry's strand kind, or the replacement cannot be represented as a PathDyn of the same URL kind (e.g. local-style name under an archive:// entry). Either the old or the new name failing triggers this.","commonSituations":"Hand-editing the buffer and leaving an empty line; scripted rewrites inserting invalid bytes; renaming entries backed by plugin URL kinds with names that kind rejects.","solutions":["Fix the flagged names in a follow-up bulk rename: non-empty, same URL kind, no invalid bytes","Inspect the failed list printed after the run to see exactly which pair failed and why it was skipped","Rename the problem file individually (normal rename flow) to surface the underlying strand error directly"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Drop pairs whose replacement is not a valid dynamic path before renaming:\nlet todo: Vec<_> = todo.into_iter()\n    .filter(|(o, n)| {\n        Self::replace_url(&selected[n.0], root, n).is_ok()\n            && Self::replace_url(&selected[o.0], root, o).is_ok()\n    })\n    .collect();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep edited names non-empty and free of NUL/control bytes","Never change the line count when editing the bulk-rename buffer","For exotic names, use single-file rename to see the underlying strand error"],"tags":["bulk-rename","paths","vfs","strand"],"backgroundTag":null,"analyzedSha":"94abcfa92f4ad3f0a1aef6c1ea083cfb8aa6c8c2","analyzedAt":"2026-08-16T09:56:24.836Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}