{"record":{"id":"76bcf2f794bcb045","repo":"beemdevelopment/Aegis","slug":"unable-to-find-pack-json-in-the-root-of-the-zip-fi","errorCode":null,"errorMessage":"Unable to find pack.json in the root of the ZIP file","messagePattern":"Unable to find pack\\.json in the root of the ZIP file","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/icons/IconPackManager.java","lineNumber":70,"sourceCode":"\n    public void removeIconPack(IconPack pack) throws IconPackException {\n        try {\n            File dir = getIconPackDir(pack);\n            deleteDir(dir);\n        } catch (IOException e) {\n            throw new IconPackException(e);\n        }\n\n        _iconPacks.remove(pack);\n    }\n\n    public IconPack importPack(File inFile) throws IconPackException {\n        try {\n            // read and parse the icon pack definition file of the icon pack\n            ZipFile zipFile = new ZipFile(inFile);\n            FileHeader packHeader = zipFile.getFileHeader(_packDefFilename);\n            if (packHeader == null) {\n                throw new IOException(\"Unable to find pack.json in the root of the ZIP file\");\n            }\n            IconPack pack;\n            byte[] defBytes;\n            try (ZipInputStream inStream = zipFile.getInputStream(packHeader)) {\n                defBytes = IOUtils.readAll(inStream);\n                pack = IconPack.fromBytes(defBytes);\n            }\n\n            // create a new directory to store the icon pack, based on the UUID and version\n            File packDir = getIconPackDir(pack);\n            if (!packDir.getCanonicalPath().startsWith(_iconsBaseDir.getCanonicalPath() + File.separator)) {\n                throw new IOException(\"Attempted to write outside of the parent directory\");\n            }\n            if (packDir.exists()) {\n                throw new IconPackExistsException(pack);\n            }\n            IconPack existingPack = getIconPackByUUID(pack.getUUID());\n            if (existingPack != null) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/icons/IconPackManager.java#L52-L88","documentation":"IconPackManager.importPack opens the uploaded ZIP and looks up the entry named \"pack.json\" at the archive root. When zipFile.getFileHeader returns null, the archive either has no such entry or only stores it in a subdirectory, so an IOException is raised and surfaced as IconPackException. This is the first sanity check that the file is actually an Aegis icon pack.","triggerScenarios":"Calling importPack with a ZIP that lacks a root-level pack.json entry: a ZIP wrapping the pack in an extra folder (pack.json under mypack/pack.json), a random ZIP file, or an archive whose definition file was renamed.","commonSituations":"Users re-zipping an extracted icon pack so an extra top-level directory is introduced; downloading the wrong archive; tools that nest files when compressing a folder instead of its contents.","solutions":["Repackage the ZIP so pack.json sits at the root (zip from inside the pack folder, not the parent)","Verify the archive contents (e.g. unzip -l) and confirm pack.json is present and not renamed","Re-download the icon pack from its official source","Ensure the file being imported is an Aegis icon pack, not another archive type"],"exampleFix":"// before (shell)\nzip -r pack.zip aegis-icons/   # pack.json ends up at aegis-icons/pack.json\n// after (shell)\ncd aegis-icons && zip -r ../pack.zip .   # pack.json at archive root","handlingStrategy":"validation","validationCode":"java.util.zip.ZipFile zf = new java.util.zip.ZipFile(inFile);\nboolean ok = zf.getEntry(\"pack.json\") != null;\nzf.close();\nif (!ok) throw new IconPackException(\"pack.json missing at ZIP root\");","typeGuard":null,"tryCatchPattern":"try {\n    iconPackManager.importPack(file);\n} catch (IconPackException e) {\n    if (e.getCause() instanceof IOException && e.getMessage().contains(\"pack.json\")) {\n        UiHelper.showDialog(context, R.string.invalid_icon_pack);\n    }\n}","preventionTips":["Zip the pack contents from inside the folder so pack.json stays at the root","Verify with unzip -l before distributing","Never rename pack.json","Document the expected archive layout for pack authors"],"tags":["zip","icon-pack","missing-file","android"],"backgroundTag":"file-not-found","analyzedSha":"d6f4e5925a97e4e91593f1542085eae03432a759","analyzedAt":"2026-09-08T00:46:31.111Z","contentChangedAt":"2026-09-08T00:46:31.111Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}