From f91e553336d0ae08f29e9fc1697f072a8fcd3876 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Sat, 19 Sep 2026 11:41:53 +0200 Subject: [PATCH] fix(desktop): send on_conflict=overwrite on move so same-name replace works (#155) Cut/paste with "replace target" emits a rename whose destination name still exists remotely; the server default fail-fast conflict produced "cloud operation failed". The OS already resolved local naming before the event, so the stale remote entity is overwritten. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- desktop/crates/cloudreve-api/src/models/explorer.rs | 6 ++++++ desktop/crates/cloudreve-sync/src/drive/commands.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/desktop/crates/cloudreve-api/src/models/explorer.rs b/desktop/crates/cloudreve-api/src/models/explorer.rs index 3b806261..285922bd 100644 --- a/desktop/crates/cloudreve-api/src/models/explorer.rs +++ b/desktop/crates/cloudreve-api/src/models/explorer.rs @@ -287,6 +287,12 @@ pub struct MoveFileService { pub dst: String, #[serde(skip_serializing_if = "Option::is_none")] pub copy: Option, + /// Behaviour when a destination child with the same name exists: + /// "skip" drops the colliding source, "overwrite" deletes the + /// destination object first. Absent keeps the server default + /// (fail with a conflict error). + #[serde(skip_serializing_if = "Option::is_none")] + pub on_conflict: Option, } /// Metadata patch diff --git a/desktop/crates/cloudreve-sync/src/drive/commands.rs b/desktop/crates/cloudreve-sync/src/drive/commands.rs index 7951bb4f..1eec8630 100644 --- a/desktop/crates/cloudreve-sync/src/drive/commands.rs +++ b/desktop/crates/cloudreve-sync/src/drive/commands.rs @@ -585,6 +585,11 @@ impl Mount { )? .to_string(), copy: None, + // The OS already resolved local naming before emitting the + // rename (Explorer prompts replace/skip; skip produces no + // event), so a remote name collision at the destination is a + // stale remote entity and must be overwritten. + on_conflict: Some("overwrite".to_string()), }) .await {