{"record":{"id":"f428c4f445b0a240","repo":"MuntashirAkon/AppManager","slug":"failed-to-get-crypto-tbconverter","errorCode":null,"errorMessage":"Failed to get crypto ","messagePattern":"Failed to get crypto ","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/TBConverter.java","lineNumber":124,"sourceCode":"            throw new BackupException(\"Could not read package name.\");\n        }\n        // Source metadata\n        mSourceMetadata = readPropFile();\n        // Simulate a backup creation\n        try {\n            mBackupItem = BackupItems.createBackupItemGracefully(mUserId, \"TB\", mPackageName);\n        } catch (IOException e) {\n            throw new BackupException(\"Could not get backup files\", e);\n        }\n        boolean backupSuccess = false;\n        try {\n            try {\n                // Destination metadata\n                mDestMetadata = ConvertUtils.getV5Metadata(mSourceMetadata, mBackupItem);\n                // Destination APK will be renamed\n                mDestMetadata.metadata.apkName = \"base.apk\";\n            } catch (CryptoException e) {\n                throw new BackupException(\"Failed to get crypto \" + mDestMetadata.info.crypto, e);\n            }\n            try {\n                mChecksum = mBackupItem.getChecksum();\n            } catch (IOException e) {\n                throw new BackupException(\"Failed to create checksum file.\", e);\n            }\n            // Backup icon\n            backupIcon();\n            if (mDestMetadata.info.flags.backupApkFiles()) {\n                backupApkFile();\n            }\n            if (mDestMetadata.info.flags.backupData()) {\n                backupData();\n            }\n            // Write modified metadata\n            try {\n                Map<String, String> filenameChecksumMap = MetadataManager.writeMetadata(mDestMetadata, mBackupItem);\n                for (Map.Entry<String, String> filenameChecksumPair : filenameChecksumMap.entrySet()) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/TBConverter.java#L106-L142","documentation":"TBConverter.convert() wraps CryptoException from ConvertUtils.getV5Metadata() (which computes the destination crypto/keystore parameters for the converted backup) into a BackupException. It means the metadata conversion could not obtain the cryptographic settings (key alias, cipher, keystore access) needed to build the v5 destination metadata.","triggerScenarios":"Calling convert() on a source backup whose destination metadata requires crypto info that cannot be resolved: ConvertUtils.getV5Metadata(mSourceMetadata, mBackupItem) throws CryptoException because the destination backup item's crypto settings (keystore/key/algorithm) are unavailable or invalid.","commonSituations":"Converting a backup to the encrypted (TAR+GZIP+CRYPTO) format without a valid keystore or a key selected; keystore file missing/corrupted; a keystore password or key alias mismatch; the destination metadata references a crypto mode unsupported by the configured encryption algorithm.","solutions":["Verify the BackupItem's crypto settings (keystore path, key alias, passwords, cipher mode) are valid before calling convert().","Re-create or re-select the encryption key/keystore, or set the backup to unencrypted if crypto is not needed.","Inspect the wrapped CryptoException cause for the underlying keystore/algorithm error and fix it accordingly."],"exampleFix":"// before\nmBackupItem.setCryptoAlgo(CryptoUtils.CRYPTO_AES_GCM); // with missing/invalid keystore\nconvert();\n// after\nif (CryptoUtils.getKeystore().isPresent()) {\n    mBackupItem.setCryptoAlgo(CryptoUtils.CRYPTO_AES_GCM);\n    convert();\n} else {\n    throw new IllegalStateException(\"Select or create a keystore key before converting to encrypted backup\");\n}","handlingStrategy":"validation","validationCode":"// Kotlin/Java pseudo-check before convert()\nif (mBackupItem.isEncrypted()) {\n    if (!CryptoUtils.hasValidKey(mDestMetadata.crypto.keyAlias)) {\n        throw new IllegalStateException(\"Configure a valid keystore key before converting to encrypted backup\");\n    }\n}","typeGuard":"fun CryptoInfo?.isValid(): Boolean = this != null && !keyAlias.isNullOrBlank() && algo != null","tryCatchPattern":"try {\n    converter.convert();\n} catch (BackupException e) {\n    if (e.getCause() instanceof CryptoException ce) {\n        Log.e(TAG, \"Crypto setup failed: \" + ce.getMessage());\n        promptUserToSelectKey();\n    }\n}","preventionTips":["Always initialize/select the keystore key before running any conversion to a crypto destination format.","Test keystore access (load + alias existence) at app startup when encrypted backups are enabled.","Keep keystore passwords in secure storage and verify the alias exists before conversion."],"tags":["crypto","keystore","backup-conversion"],"backgroundTag":"missing-credentials","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"}