MuntashirAkon/AppManager · error · IOException

Error occurred during en/decryption process

Error message

Error occurred during en/decryption process

What it means

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.

Solutions

  1. Inspect the OpenPGP error result (get OpenPgpError from the result Intent via OpenPgpApi.RESULT_ERROR) to see the root cause
  2. Ensure the requested key user-IDs exist and are usable in the OpenPGP provider (OpenKeychain)
  3. Allow user interaction (handle RESULT_CODE_USER_INTERACTION_REQUIRED with pending intent) or pre-authorize the key passphrase
  4. Run doAction on a worker thread and waitForResult() so the result handling completes before the flag check

Example fix

// before
Intent result = api.executeApi(intent, is, os);
if (result.getIntExtra(OpenPgpApi.RESULT_CODE, -1) != OpenPgpApi.RESULT_CODE_SUCCESS) {
    OpenPgpError err = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
    Log.e(TAG, "OpenPGP error: " + err.getMessage());
}
// after: fix key selection in OpenKeychain or supply valid keyIds
intent.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{"user@example.com"});
Intent result = api.executeApi(intent, is, os);
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling, verify the provider has usable keys
OpenPgpKeyIds ids = new OpenPgpKeyIds(context);
long[] keyIds = ids.getEncryptionKeyIds(new String[]{"user@example.com"});
if (keyIds == null || keyIds.length == 0) { /* prompt user to set up keys */ }

Try / catch

try {
    crypto.doAction(Crypto.OPEN_ENCRYPT, in, out);
} catch (IOException e) {
    if (e.getMessage().contains("Error occurred during en/decryption")) {
        // retrieve last OpenPgpApi.RESULT_ERROR intent for the real cause
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/ea1fbe1b822d660c. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java:201

            Log.d(TAG, "No files to de/encrypt");
            return;
        }
        if (mInputFiles.length != mOutputFiles.length) {
            throw new IOException("The number of input and output files are not the same.");
        }
        for (int i = 0; i < mInputFiles.length; i++) {
            Path inputPath = mInputFiles[i];
            Path outputPath = mOutputFiles[i];
            Log.i(TAG, "Input: %s\nOutput: %s", inputPath, outputPath);
            InputStream is = inputPath.openInputStream();
            OutputStream os = outputPath.openOutputStream();
            OpenPgpApi api = new OpenPgpApi(mContext, mService.getService());
            Intent result = api.executeApi(intent, is, os);
            mHandler.post(() -> handleResult(result));
            if (waitForResult) waitForResult();
            if (mErrorFlag) {
                outputPath.delete();
                throw new IOException("Error occurred during en/decryption process");
            }
        }
        // Total success
    }

    @WorkerThread
    private void doActionForStream(Intent intent, boolean waitForResult) throws IOException {
        mErrorFlag = false;
        OpenPgpApi api = new OpenPgpApi(mContext, mService.getService());
        Intent result = api.executeApi(intent, mIs, mOs);
        mHandler.post(() -> handleResult(result));
        if (waitForResult) waitForResult();
        if (mErrorFlag) {
            throw new IOException("Error occurred during en/decryption process");
        }
    }

    private void bind() {

View on GitHub (pinned to 0152f468fc)