{"record":{"id":"89ef234f6611d11e","repo":"libnyanpasu/clash-nyanpasu","slug":"materialization-has-multiple-backups","errorCode":null,"errorMessage":"materialization has multiple backups","messagePattern":"materialization has multiple backups","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/service/profile_file.rs","lineNumber":854,"sourceCode":"        let link_path = Self::backup_link_path(root, operation_id);\n        let file_metadata = match std::fs::symlink_metadata(&file_path) {\n            Ok(metadata) => Some(metadata),\n            Err(error) if error.kind() == std::io::ErrorKind::NotFound => None,\n            Err(error) => {\n                return Err(error)\n                    .with_context(|| format!(\"inspect backup file {}\", file_path.display()));\n            }\n        };\n        let link_metadata = match std::fs::symlink_metadata(&link_path) {\n            Ok(metadata) => Some(metadata),\n            Err(error) if error.kind() == std::io::ErrorKind::NotFound => None,\n            Err(error) => {\n                return Err(error)\n                    .with_context(|| format!(\"inspect backup link {}\", link_path.display()));\n            }\n        };\n        if file_metadata.is_some() && link_metadata.is_some() {\n            bail!(\"materialization has multiple backups\");\n        }\n        if let Some(metadata) = file_metadata {\n            if is_symlink_or_reparse(&metadata) || !metadata.is_file() {\n                bail!(\"backup file is not a regular file\");\n            }\n            return Ok(Some(StoredResource::File { path: file_path }));\n        }\n        if let Some(metadata) = link_metadata {\n            if is_symlink_or_reparse(&metadata) || !metadata.is_file() {\n                bail!(\"backup symlink specification is not a regular file\");\n            }\n            let target = std::fs::read_to_string(&link_path)?;\n            return Ok(Some(StoredResource::Symlink {\n                target: ExternalProfilePath::new(target)?,\n            }));\n        }\n        Ok(None)\n    }","sourceCodeStart":836,"sourceCodeEnd":872,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/service/profile_file.rs#L836-L872","documentation":"read_backup_resource reads the rollback backup for an operation and expects at most one backup resource (a file blob OR a symlink-spec file) per operation_id under the backup root. Both the backup file path and the backup link path exist, which is an inconsistent state, so the code aborts rather than restoring an ambiguous backup.","triggerScenarios":"Both backup_file_path(root, operation_id) and backup_link_path(root, operation_id) exist when read_backup_resource is called — e.g. the same operation_id was used for two materializations where the managed target was first a file and then a symlink, and the earlier backup was never cleaned up.","commonSituations":"Reused operation IDs across sequential materializations; a failed run that wrote one backup kind, then a retried run wrote the other without cleanup; manual restoration of backup directories merging old and new backups.","solutions":["Delete the backup directory contents for this operation_id and re-run the operation so exactly one backup is captured.","Re-run with a fresh operation_id to get a clean backup area.","Ensure operation cleanup (removal of backup files) runs after successful promotion, and serialize operations sharing an operation_id.","If one of the two files is clearly stale (older mtime), remove it — but prefer a clean re-run."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let f = backup_file_path(root, op_id);\nlet l = backup_link_path(root, op_id);\nif f.exists() && l.exists() {\n    std::fs::remove_dir_all(backup_dir(root, op_id))?; // clear ambiguous backups\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"multiple backups\") => {\n        clear_backup_dir(root, op_id)?;\n        retry_with_fresh_operation_id()\n    }\n    other => other,\n}","preventionTips":["Use unique operation_ids per materialization run.","Ensure backup files are cleaned up after successful promotion/rollback.","Don't merge or manually restore backup directories across operations."],"tags":["filesystem","backup","state-inconsistency","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}