{"record":{"id":"1dddfa51ecf18464","repo":"MuntashirAkon/AppManager","slug":"missing-manifest-file","errorCode":null,"errorMessage":"Missing {MANIFEST_FILE}","messagePattern":"Missing (.+?)","errorType":"exception","errorClass":"ApkFormatException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkUtils.java","lineNumber":331,"sourceCode":"        }\n        return writableExtDir;\n    }\n\n    public static int getDensityFromName(@Nullable String densityName) {\n        Integer density = StaticDataset.DENSITY_NAME_TO_DENSITY.get(densityName);\n        if (density == null) {\n            throw new IllegalArgumentException(\"Unknown density \" + densityName);\n        }\n        return density;\n    }\n\n    @NonNull\n    private static ByteBuffer getAndroidManifestFromApk(\n            @NonNull List<CentralDirectoryRecord> cdRecords, @NonNull DataSource lhfSection)\n            throws IOException, ApkFormatException, ZipFormatException {\n        CentralDirectoryRecord androidManifestCdRecord = findCdRecord(cdRecords, MANIFEST_FILE);\n        if (androidManifestCdRecord == null) {\n            throw new ApkFormatException(\"Missing \" + MANIFEST_FILE);\n        }\n        return ByteBuffer.wrap(LocalFileRecord.getUncompressedData(\n                lhfSection, androidManifestCdRecord, lhfSection.size()));\n    }\n\n    @Nullable\n    private static CentralDirectoryRecord findCdRecord(\n            @NonNull List<CentralDirectoryRecord> cdRecords, @NonNull String name) {\n        for (CentralDirectoryRecord cdRecord : cdRecords) {\n            if (name.equals(cdRecord.getName())) {\n                return cdRecord;\n            }\n        }\n        return null;\n    }\n}\n","sourceCodeStart":313,"sourceCodeEnd":348,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/apk/ApkUtils.java#L313-L348","documentation":"getAndroidManifestFromApk scans the APK's central directory records for the AndroidManifest.xml entry (MANIFEST_FILE) and throws ApkFormatException when the entry is absent. An APK without a manifest is not a valid installable package, so manifest extraction cannot proceed.","triggerScenarios":"Calling ApkUtils.getManifestFromApk on a file whose ZIP central directory lacks an AndroidManifest.xml record — e.g. the file is not an APK (a plain ZIP, XAPK/APKS container, or split), or the manifest was stripped during repackaging.","commonSituations":"Pointing the tool at .apks/.xapk archives instead of the base .apk, corrupted downloads where the central directory is truncated, or obfuscated/stripped APKs from modified toolchains.","solutions":["Verify the input is a real APK: unzip -l file.apk | grep AndroidManifest.xml must list the entry.","If using .apks/.xapk containers, extract the base APK first and pass that to getManifestFromApk.","Re-download or re-export the APK; a missing manifest entry usually means a corrupt or non-APK file.","Catch ApkFormatException and reject the file before attempting installation or further parsing."],"exampleFix":"// before\nByteBuffer manifest = ApkUtils.getManifestFromApk(apkPath);\n// after\ntry {\n    ByteBuffer manifest = ApkUtils.getManifestFromApk(apkPath);\n} catch (ApkFormatException e) {\n    throw new IOException(\"Not a valid APK (no AndroidManifest.xml): \" + apkPath, e);\n}","handlingStrategy":"validation","validationCode":"try (ZipFile zf = new ZipFile(apkPath)) {\n    if (zf.getEntry(\"AndroidManifest.xml\") == null)\n        throw new IOException(\"Not an APK: AndroidManifest.xml missing\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ByteBuffer manifest = ApkUtils.getManifestFromApk(apkPath);\n} catch (ApkFormatException | ZipFormatException e) {\n    Log.e(TAG, \"Invalid APK: \" + e.getMessage(), e);\n}","preventionTips":["Verify the file extension and content: .apks/.xapk containers must be extracted to the base APK first.","Check file integrity (size/checksum) after download before parsing.","Run aapt dump badging as a cheap pre-flight validation.","Reject files whose central directory cannot list AndroidManifest.xml."],"tags":["apk","zip","manifest","file-not-found"],"backgroundTag":"resource-not-found","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"}