{"record":{"id":"0df52e97683eeef6","repo":"MuntashirAkon/AppManager","slug":"mode-restoreop","errorCode":null,"errorMessage":"Mode ","messagePattern":"Mode ","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java","lineNumber":122,"sourceCode":"    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        }\n        // Get checksums\n        try {\n            mChecksum = mBackupItem.getChecksum();\n        } catch (Throwable e) {\n            mBackupItem.cleanup();","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/RestoreOp.java#L104-L140","documentation":"RestoreOp checks CryptoUtils.isAvailable(mBackupInfo.crypto) after reading backup info and throws BackupException when the crypto mode recorded in the backup is not usable on this device. The message embeds the unavailable mode name after the prefix 'Mode '.","triggerScenarios":"backup.json lists a crypto mode (e.g. MasterCrypt, ECryptfs, OpenPGP) that is not installed/usable on the restoring device; isAvailable returns false and the constructor aborts.","commonSituations":"Backup created on a device with MasterCrypt/ECryptfs support, restored on a stock ROM lacking the kernel module; OpenPGP provider not installed; mode renamed between app versions.","solutions":["Install/enable the missing crypto provider named in the message (e.g. OpenPGP app, MasterCrypt-enabled ROM)","Re-create the backup using a universally available crypto mode (e.g. standard password-based mode) or no encryption","Check CryptoUtils.getMode alternatives supported on the current device before restoring","If the backup was encrypted but you only need unencrypted files, regenerate backup.json with crypto set appropriately"],"exampleFix":"// before\nif (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {\n    throw new BackupException(\"Mode \" + mBackupInfo.crypto + \" is currently unavailable.\");\n}\n// after\nif (!CryptoUtils.isAvailable(mBackupInfo.crypto)) {\n    String[] supported = CryptoUtils.getSupportedModes();\n    throw new BackupException(\"Mode \" + mBackupInfo.crypto + \" unavailable. Supported: \"\n            + Arrays.toString(supported) + \". Install the provider or re-create the backup.\");\n}","handlingStrategy":"validation","validationCode":"if (!CryptoUtils.isAvailable(mode)) {\n    throw new BackupException(\"Crypto mode \" + mode + \" unavailable on this device; install the provider or re-create the backup.\");\n}","typeGuard":"boolean modeSupported(String mode) { return mode == null || CryptoUtils.isAvailable(mode); }","tryCatchPattern":"try { new RestoreOp(...); } catch (BackupException e) { if (e.getMessage().startsWith(\"Mode \") && e.getMessage().contains(\"unavailable\")) { installCryptoProviderOrReencrypt(); } throw e; }","preventionTips":["Record supported crypto modes at backup time and check them on the restore target","Prefer portable crypto modes when creating backups destined for other devices","Keep the crypto provider app (e.g. OpenPGP) installed before restoring"],"tags":["crypto","android","backup","unsupported-feature"],"backgroundTag":"unsupported-operation","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"}