{"record":{"id":"5c8a8b6cc88fbab3","repo":"Universal-Debloater-Alliance/universal-android-debloater-next-generation","slug":"unable-to-parse-backup-file","errorCode":null,"errorMessage":"Unable to parse backup file","messagePattern":"Unable to parse backup file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/uad-core/src/save.rs","lineNumber":82,"sourceCode":"        Err(err) => Err(err.to_string()),\n    }\n}\n\npub fn list_available_backups(dir: &Path) -> Vec<DisplayablePath> {\n    match fs::read_dir(dir) {\n        Ok(files) => files\n            .filter_map(Result::ok)\n            .map(|e| DisplayablePath { path: e.path() })\n            .collect::<Vec<_>>(),\n        Err(_) => vec![],\n    }\n}\n\n#[must_use]\npub fn list_available_backup_user(backup: DisplayablePath) -> Vec<User> {\n    match fs::read_to_string(backup.path) {\n        Ok(data) => serde_json::from_str::<PhoneBackup>(&data)\n            .expect(\"Unable to parse backup file\")\n            .users\n            .into_iter()\n            .map(|u| User {\n                id: u.id,\n                index: 0,\n                protected: false,\n            })\n            .collect(),\n        Err(e) => {\n            error!(\"[BACKUP]: Selected backup file not found: {e}\");\n            vec![]\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct BackupPackage {\n    pub i_user: usize,","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/64465c850c7ed36329e67165ac08501abffb218e/crates/uad-core/src/save.rs#L64-L100","documentation":"list_available_backup_user reads a backup file and deserializes it into PhoneBackup with serde_json; malformed JSON panics with \"Unable to parse backup file\". The library assumes any selected .backup/.json file is a valid UAD phone backup.","triggerScenarios":"Calling list_available_backup_user(backup) with a file that is not valid JSON, is an older/incompatible backup schema, is empty, or has a different encoding (UTF-16/BOM).","commonSituations":"User selects a random or renamed file in the restore dialog; backups exported by an older UAD version with a changed PhoneBackup schema; truncated downloads.","solutions":["Validate the file with a JSON linter or `jq . file` to confirm it parses.","Confirm the backup was exported by a compatible UAD version (PhoneBackup schema).","Re-export the backup from the original device.","Wrap parsing with serde_json::from_str(...).ok()/Result handling and show a user-facing error instead of panicking."],"exampleFix":"// before\nserde_json::from_str::<PhoneBackup>(&data).expect(\"Unable to parse backup file\")\n// after\nlet phone_backup: PhoneBackup = serde_json::from_str(&data)\n    .map_err(|e| error!(\"Unable to parse backup file: {e}\")).unwrap_or_default();","handlingStrategy":"validation","validationCode":"fn is_valid_uad_backup(path: &std::path::Path) -> bool {\n    std::fs::read_to_string(path)\n        .ok()\n        .and_then(|s| serde_json::from_str::<serde_json::Value>(&s).ok())\n        .map(|v| v.get(\"users\").is_some())\n        .unwrap_or(false)\n}","typeGuard":"fn is_phone_backup(v: &serde_json::Value) -> bool {\n    v.get(\"users\").and_then(|u| u.as_array()).map(|a| a.iter().all(|x| x.get(\"id\").is_some())).unwrap_or(false)\n}","tryCatchPattern":"match std::fs::read_to_string(backup.path) {\n    Ok(data) => match serde_json::from_str::<PhoneBackup>(&data) {\n        Ok(pb) => { /* use pb.users */ }\n        Err(e) => eprintln!(\"Unable to parse backup file: {e}\"),\n    },\n    Err(e) => eprintln!(\"read failed: {e}\"),\n}","preventionTips":["Only select backups exported by a compatible UAD version.","Validate JSON with `jq .` before importing.","Never hand-edit backup files without re-validating.","Check UTF-8 encoding and absence of BOM/UTF-16."],"tags":["json","serde","panic","backup"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"64465c850c7ed36329e67165ac08501abffb218e","analyzedAt":"2026-09-12T09:09:23.137Z","contentChangedAt":"2026-09-12T09:09:23.137Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}