{"record":{"id":"a0e5f24ad3b17b2f","repo":"beemdevelopment/Aegis","slug":"unable-to-find-s-relative-to-the-root-of-the-zip","errorCode":null,"errorMessage":"Unable to find %s relative to the root of the ZIP file","messagePattern":"Unable to find (.+?) relative to 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":103,"sourceCode":"                throw new IconPackExistsException(pack);\n            }\n            IconPack existingPack = getIconPackByUUID(pack.getUUID());\n            if (existingPack != null) {\n                throw new IconPackExistsException(existingPack);\n            }\n            if (!packDir.exists() && !packDir.mkdirs()) {\n                throw new IOException(String.format(\"Unable to create directories: %s\", packDir.toString()));\n            }\n\n            // extract each of the defined icons to the icon pack directory\n            for (IconPack.Icon icon : pack.getIcons()) {\n                File destFile = new File(packDir, icon.getRelativeFilename());\n                if (!destFile.getCanonicalPath().startsWith(packDir.getCanonicalPath() + File.separator)) {\n                    throw new IOException(\"Attempted to write outside of the icon pack directory\");\n                }\n                FileHeader iconHeader = zipFile.getFileHeader(icon.getRelativeFilename());\n                if (iconHeader == null) {\n                    throw new IOException(String.format(\"Unable to find %s relative to the root of the ZIP file\", icon.getRelativeFilename()));\n                }\n\n                // create new directories for this file if needed\n                File parent = destFile.getParentFile();\n                if (parent != null && !parent.exists() && !parent.mkdirs()) {\n                    throw new IOException(String.format(\"Unable to create directories: %s\", packDir.toString()));\n                }\n\n                try (ZipInputStream inStream = zipFile.getInputStream(iconHeader);\n                     FileOutputStream outStream = new FileOutputStream(destFile)) {\n                    IOUtils.copy(inStream, outStream);\n                }\n\n                // after successful copy of the icon, store the new filename\n                icon.setFile(destFile);\n            }\n\n            // write the icon pack definition file to the newly created directory","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/icons/IconPackManager.java#L85-L121","documentation":"After passing the path-safety check, importPack looks up each icon's relative filename as a ZIP entry at the archive root. If the entry is missing (zipFile.getFileHeader returns null), the pack definition references a file that isn't in the archive, so an IOException naming the missing relative path is thrown and wrapped as IconPackException.","triggerScenarios":"Importing an icon pack where pack.json lists icons whose files were not added to the ZIP, were renamed, or live in a subdirectory while the definition expects them at the root.","commonSituations":"Pack author edits pack.json to add icons but forgets to add the image files before zipping; re-zipping introduces a nested folder so entries shift; icons deleted from the archive after the definition was written.","solutions":["Rebuild the ZIP so every icon file named in pack.json exists at the archive root","Compare pack.json's icon list against the actual ZIP entries (unzip -l) and fix mismatches","Re-download the icon pack from its official source","If you authored the pack, add the missing icon files before redistributing"],"exampleFix":"// before (shell)\nzip pack.zip pack.json            # forgot the icon files\n// after (shell)\ncd aegis-icons && zip ../pack.zip pack.json *.png","handlingStrategy":"validation","validationCode":"java.util.zip.ZipFile zf = new java.util.zip.ZipFile(inFile);\nfor (IconPack.Icon icon : pack.getIcons()) {\n    if (zf.getEntry(icon.getRelativeFilename()) == null) {\n        throw new IconPackException(\"Missing ZIP entry: \" + icon.getRelativeFilename());\n    }\n}\nzf.close();","typeGuard":null,"tryCatchPattern":"try {\n    iconPackManager.importPack(file);\n} catch (IconPackException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unable to find\")) {\n        UiHelper.showDialog(context, R.string.incomplete_icon_pack);\n    }\n}","preventionTips":["Rebuild the archive so every icon in pack.json is present at the root","Diff pack.json's icon list against actual ZIP entries before distribution","Re-download packs instead of repairing them by hand","Add a pack build script that fails if any listed icon is missing"],"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"}