{"record":{"id":"7e531da09ace5c1f","repo":"MuntashirAkon/AppManager","slug":"couldn-t-decompress","errorCode":null,"errorMessage":"Couldn't decompress ","messagePattern":"Couldn't decompress ","errorType":"exception","errorClass":"BackupException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/TBConverter.java","lineNumber":209,"sourceCode":"             BufferedInputStream bis = new BufferedInputStream(pis)) {\n            CompressorInputStream is;\n            if (TAR_GZIP.equals(mSourceMetadata.tarType)) {\n                is = new GzipCompressorInputStream(bis, true);\n            } else if (TAR_BZIP2.equals(mSourceMetadata.tarType)) {\n                is = new BZip2CompressorInputStream(bis, true);\n            } else {\n                baseApkFile.requireParent().delete();\n                throw new BackupException(\"Invalid source compression type: \" + mSourceMetadata.tarType);\n            }\n            try (OutputStream fos = baseApkFile.openOutputStream()) {\n                // The whole file is the APK\n                IoUtils.copy(is, fos);\n            } finally {\n                is.close();\n            }\n        } catch (IOException e) {\n            baseApkFile.requireParent().delete();\n            throw new BackupException(\"Couldn't decompress \" + mSourceMetadata.apkName, e);\n        }\n        // Get certificate checksums\n        try {\n            String[] checksums = ConvertUtils.getChecksumsFromApk(baseApkFile, mDestMetadata.info.checksumAlgo);\n            for (int i = 0; i < checksums.length; ++i) {\n                mChecksum.add(CERT_PREFIX + i, checksums[i]);\n            }\n        } catch (Exception ignore) {\n        }\n        // Backup APK file\n        String sourceBackupFilePrefix = BackupUtils.getSourceFilePrefix(getExt(mDestMetadata.info.tarType));\n        Path[] sourceFiles;\n        try {\n            sourceFiles = TarUtils.create(mDestMetadata.info.tarType, baseApkFile, mBackupItem.getUnencryptedBackupPath(), sourceBackupFilePrefix,\n                            /* language=regexp */new String[]{\".*\\\\.apk\"}, null, null, false)\n                    .toArray(new Path[0]);\n        } catch (Throwable th) {\n            throw new BackupException(\"APK files backup is requested but no APK files have been backed up.\", th);","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/convert/TBConverter.java#L191-L227","documentation":"While streaming the decompressed APK from the source archive to a staging file, any IOException is wrapped as \"Couldn't decompress <apkName>\". It means the source APK archive could not be read/decompressed or the staged APK file could not be written.","triggerScenarios":"IoUtils.copy(is, fos) or closing the streams throws IOException: the source tar/compressed stream is truncated or corrupted (bad gzip/bzip2 block), the source file is unreadable, or writing to the staging directory fails (space/permissions).","commonSituations":"Source backup files partially copied from a PC or cloud, yielding corrupt .gz/.bz2 archives; disk full while staging the APK; SD card removed mid-operation; source file renamed/deleted after metadata was read.","solutions":["Verify the source backup archive integrity (try decompressing it manually; check gzip/bzip2 test passes).","Re-transfer or re-create the source backup if the archive is truncated or corrupt.","Check free space and write permissions in the staging/temp directory.","Confirm the APK file referenced by mSourceMetadata.apkName still exists in the source backup."],"exampleFix":"// before\n// blindly converting possibly corrupted source\nconvert();\n// after\nif (!DigestUtils.matchesHexDigest(archivePath, sourceMetadata.checksums.get(\"apk\"))) {\n    throw new IOException(\"Source APK archive corrupted; re-transfer the backup\");\n}\nconvert();","handlingStrategy":"validation","validationCode":"// Verify source archive integrity before conversion\nif (!DigestUtils.getHexDigest(checksumAlgo, sourceApkArchive)\n        .equals(sourceMetadata.checksums.get(\"apk\"))) {\n    throw new IOException(\"Source APK archive checksum mismatch — re-transfer backup\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    converter.convert();\n} catch (BackupException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Couldn't decompress\")) {\n        verifySourceIntegrity(); // run gzip/bzip2 -t and tar listing; re-transfer if corrupt\n    }\n}","preventionTips":["Always verify source backup checksums before converting.","Avoid interrupted transfers: re-copy from a stable source if the archive came from PC/cloud.","Ensure ample free space in the staging directory before extraction."],"tags":["io","decompression","corrupt-archive"],"backgroundTag":"file-read-failed","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"}