{"record":{"id":"ea1fbe1b822d660c","repo":"MuntashirAkon/AppManager","slug":"error-occurred-during-en-decryption-process","errorCode":null,"errorMessage":"Error occurred during en/decryption process","messagePattern":"Error occurred during en/decryption process","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java","lineNumber":201,"sourceCode":"            Log.d(TAG, \"No files to de/encrypt\");\n            return;\n        }\n        if (mInputFiles.length != mOutputFiles.length) {\n            throw new IOException(\"The number of input and output files are not the same.\");\n        }\n        for (int i = 0; i < mInputFiles.length; i++) {\n            Path inputPath = mInputFiles[i];\n            Path outputPath = mOutputFiles[i];\n            Log.i(TAG, \"Input: %s\\nOutput: %s\", inputPath, outputPath);\n            InputStream is = inputPath.openInputStream();\n            OutputStream os = outputPath.openOutputStream();\n            OpenPgpApi api = new OpenPgpApi(mContext, mService.getService());\n            Intent result = api.executeApi(intent, is, os);\n            mHandler.post(() -> handleResult(result));\n            if (waitForResult) waitForResult();\n            if (mErrorFlag) {\n                outputPath.delete();\n                throw new IOException(\"Error occurred during en/decryption process\");\n            }\n        }\n        // Total success\n    }\n\n    @WorkerThread\n    private void doActionForStream(Intent intent, boolean waitForResult) throws IOException {\n        mErrorFlag = false;\n        OpenPgpApi api = new OpenPgpApi(mContext, mService.getService());\n        Intent result = api.executeApi(intent, mIs, mOs);\n        mHandler.post(() -> handleResult(result));\n        if (waitForResult) waitForResult();\n        if (mErrorFlag) {\n            throw new IOException(\"Error occurred during en/decryption process\");\n        }\n    }\n\n    private void bind() {","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java#L183-L219","documentation":"After OpenPgpApi.executeApi runs, the result Intent is handled asynchronously (handleResult sets mErrorFlag). If waitForResult returns and the flag is set, the operation failed (user cancel, provider error, bad key), the partial output file is deleted, and an IOException is thrown.","triggerScenarios":"doActionForFiles with waitForResult=true when the OpenPGP provider returns error result codes (RESULT_CODE_ERROR, RESULT_CODE_USER_INTERACTION_REQUIRED unhandled, key selection problems) during a per-file encrypt/decrypt.","commonSituations":"Missing or wrong encryption key/user IDs in provider settings; OpenKeychain prompting for passphrase when the caller doesn't allow interaction; expired/revoked recipient keys; provider returning error for one file in a batch.","solutions":["Inspect the OpenPGP error result (get OpenPgpError from the result Intent via OpenPgpApi.RESULT_ERROR) to see the root cause","Ensure the requested key user-IDs exist and are usable in the OpenPGP provider (OpenKeychain)","Allow user interaction (handle RESULT_CODE_USER_INTERACTION_REQUIRED with pending intent) or pre-authorize the key passphrase","Run doAction on a worker thread and waitForResult() so the result handling completes before the flag check"],"exampleFix":"// before\nIntent result = api.executeApi(intent, is, os);\nif (result.getIntExtra(OpenPgpApi.RESULT_CODE, -1) != OpenPgpApi.RESULT_CODE_SUCCESS) {\n    OpenPgpError err = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);\n    Log.e(TAG, \"OpenPGP error: \" + err.getMessage());\n}\n// after: fix key selection in OpenKeychain or supply valid keyIds\nintent.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{\"user@example.com\"});\nIntent result = api.executeApi(intent, is, os);","handlingStrategy":"try-catch","validationCode":"// before calling, verify the provider has usable keys\nOpenPgpKeyIds ids = new OpenPgpKeyIds(context);\nlong[] keyIds = ids.getEncryptionKeyIds(new String[]{\"user@example.com\"});\nif (keyIds == null || keyIds.length == 0) { /* prompt user to set up keys */ }","typeGuard":null,"tryCatchPattern":"try {\n    crypto.doAction(Crypto.OPEN_ENCRYPT, in, out);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Error occurred during en/decryption\")) {\n        // retrieve last OpenPgpApi.RESULT_ERROR intent for the real cause\n    }\n}","preventionTips":["Capture RESULT_ERROR / OpenPgpError from the result Intent for diagnostics","Handle RESULT_CODE_USER_INTERACTION_REQUIRED (passphrase/consent prompts)","Validate recipient user-IDs exist in OpenKeychain before encrypting","Run on a worker thread so waitForResult actually observes the result"],"tags":["openpgp","crypto","intent","android"],"backgroundTag":"api-error-response","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}