{"record":{"id":"ba396438e8f29990","repo":"MuntashirAkon/AppManager","slug":"could-not-read-backup-info-possibly-due-to-a-malformed-json","errorCode":null,"errorMessage":"Could not read backup info. Possibly due to a malformed json file.","messagePattern":"Could not read backup info\\. Possibly due to a malformed json file\\.","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":117,"sourceCode":"    private int mUid;\n    @NonNull\n    private final BackupItems.Checksum mChecksum;\n    private final int mUserId;\n    private boolean mIsInstalled;\n    private boolean mRequiresRestart;\n\n    RestoreOp(@NonNull String packageName, @NonNull BackupFlags requestedFlags,\n              @NonNull BackupItems.BackupItem backupItem, int userId) throws BackupException {\n        mPackageName = packageName;\n        mRequestedFlags = requestedFlags;\n        mBackupItem = backupItem;\n        mUserId = userId;\n        try {\n            mBackupInfo = mBackupItem.getInfo();\n            mBackupFlags = mBackupInfo.flags;\n        } catch (IOException e) {\n            mBackupItem.cleanup();\n            throw new BackupException(\"Could not read backup info. Possibly due to a malformed json file.\", e);\n        }\n        // Setup crypto\n        if (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {\n            mBackupItem.cleanup();\n            throw new BackupException(\"Mode \" + mBackupInfo.crypto + \" is currently unavailable.\");\n        }\n        try {\n            mBackupItem.setCrypto(mBackupInfo.getCrypto());\n        } catch (CryptoException e) {\n            mBackupItem.cleanup();\n            throw new BackupException(\"Could not get crypto \" + mBackupInfo.crypto, e);\n        }\n        try {\n            mBackupMetadata = mBackupItem.getMetadata(mBackupInfo).metadata;\n        } catch (IOException e) {\n            mBackupItem.cleanup();\n            throw new BackupException(\"Could not read backup metadata. Possibly due to a malformed json file.\", e);\n        }","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L99-L135","documentation":"RestoreOp's constructor reads backup.json via mBackupItem.getInfo(); an IOException there is rethrown as BackupException stating the backup info JSON is likely malformed. The constructor aborts and cleans up the BackupItem before any restore work starts.","triggerScenarios":"mBackupItem.getInfo() throws IOException because backup.json is missing, unreadable, or fails JSON parsing (corrupt/empty file, wrong charset, truncated transfer).","commonSituations":"Backups copied off-device incompletely (no backup.json), file corrupted by cloud sync or MTP transfer, user renamed/edited backup.json manually, or permissions prevent reading the backup directory.","solutions":["Check that backup.json exists and is valid JSON inside the backup directory (validate with a JSON parser)","Re-copy the backup folder intact; verify file sizes after transfer","Restore file read permissions on the backup directory for the app","If the backup cannot be repaired, re-create the backup from the source device"],"exampleFix":"// before\nmBackupInfo = mBackupItem.getInfo();\n// after\nFile info = new File(backupDir, \"backup.json\");\nif (!info.exists() || info.length() == 0) {\n    throw new BackupException(\"backup.json is missing or empty in \" + backupDir);\n}\nmBackupInfo = mBackupItem.getInfo(); // malformed JSON still surfaces as this error","handlingStrategy":"validation","validationCode":"File f = new File(backupDir, \"backup.json\");\nif (!f.isFile() || f.length() == 0) throw new BackupException(\"backup.json missing/empty in \" + backupDir);\ntry (Reader r = new FileReader(f)) { new JsonParser().parse(r); } catch (JsonParseException e) { throw new BackupException(\"backup.json is not valid JSON\", e); }","typeGuard":"boolean hasValidBackupInfo(Path dir) { File f = dir.resolve(\"backup.json\").toFile(); return f.isFile() && f.length() > 0; }","tryCatchPattern":"try { new RestoreOp(...); } catch (BackupException e) { if (e.getMessage().contains(\"malformed json\")) { reportCorruptBackup(backupDir); } throw e; }","preventionTips":["Copy backup directories as a whole and verify file counts/sizes afterwards","Never hand-edit backup.json","Validate JSON after every backup transfer before deleting the source"],"tags":["json","backup","restore","android"],"backgroundTag":"json-parse-error","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}