{"record":{"id":"8828ce293c0be6f5","repo":"spacedriveapp/spacedrive","slug":"failed-to-move-entry","errorCode":null,"errorMessage":"Failed to move entry: {}","messagePattern":"Failed to move entry: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/indexing/change_detection/persistent.rs","lineNumber":311,"sourceCode":"\t\t} else if let Ok(Some(parent_id)) =\n\t\t\tDatabaseStorage::resolve_parent_id(&self.db, new_parent_path).await\n\t\t{\n\t\t\tstate\n\t\t\t\t.entry_id_cache\n\t\t\t\t.insert(new_parent_path.to_path_buf(), parent_id);\n\t\t\tself.entry_id_cache\n\t\t\t\t.insert(new_parent_path.to_path_buf(), parent_id);\n\t\t}\n\t\tDatabaseStorage::move_entry(\n\t\t\t&mut state,\n\t\t\t&self.db,\n\t\t\tentry.id,\n\t\t\told_path,\n\t\t\tnew_path,\n\t\t\tnew_parent_path,\n\t\t)\n\t\t.await\n\t\t.map_err(|e| anyhow::anyhow!(\"Failed to move entry: {}\", e))?;\n\n\t\tself.entry_id_cache.remove(old_path);\n\t\tself.entry_id_cache.insert(new_path.to_path_buf(), entry.id);\n\n\t\tOk(())\n\t}\n\n\tasync fn delete(&mut self, entry: &EntryRef) -> Result<()> {\n\t\tlet mut to_delete_ids: Vec<i32> = vec![entry.id];\n\n\t\tif let Ok(rows) = entities::entry_closure::Entity::find()\n\t\t\t.filter(entities::entry_closure::Column::AncestorId.eq(entry.id))\n\t\t\t.all(&self.db)\n\t\t\t.await\n\t\t{\n\t\t\tto_delete_ids.extend(rows.into_iter().map(|r| r.descendant_id));\n\t\t}\n","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/indexing/change_detection/persistent.rs#L293-L329","documentation":"DatabaseStorage::move_entry failed while relocating an entry from old_path to new_path during change detection. Moves touch the entry row, its path materialization, and the entry_closure hierarchy, so failures commonly come from a unique-path conflict at the destination, a stale parent id from entry_id_cache, or closure-table rebuild errors.","triggerScenarios":"Destination path already occupied by another entry; parent directory row deleted concurrently; closure table in inconsistent state from an earlier crashed move; DB lock contention.","commonSituations":"Rapid rename chains (a → b → c) processed out of order by watcher workers; moving entries into directories that were themselves just moved; two locations overlapping on the same physical paths.","solutions":["Check the wrapped error for unique-path conflicts and resolve by re-scanning the destination directory","Invalidate entry_id_cache for the parent before the move if the parent was recently created/moved","Verify entry_closure integrity for the subtree when moves repeatedly fail"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check the destination is free before initiating a move\nif self.find_by_path(new_path).await?.is_some() {\n    // destination occupied: scan/resolution needed before moving\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = DatabaseStorage::move_entry(&mut state, &self.db, entry.id, old_path, new_path, new_parent_path).await {\n    if e.to_string().contains(\"UNIQUE\") {\n        // destination conflict: re-scan destination dir and drop stale cache\n        self.entry_id_cache.remove(new_parent_path);\n    }\n    return Err(anyhow::anyhow!(\"Failed to move entry: {}\", e));\n}","preventionTips":["Order watcher move events (process parents before children, a→b before b→c)","Invalidate cached parent ids whenever the parent itself was moved","Periodically verify entry_closure consistency for heavily-renamed trees"],"tags":["indexing","database","move","rename","change-detection"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}