{"record":{"id":"7692d1e8b33f0e18","repo":"HMCL-dev/HMCL","slug":"malformed-datapack-zip","errorCode":null,"errorMessage":"Malformed datapack zip","messagePattern":"Malformed datapack zip","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/addon/datapack/DataPack.java","lineNumber":74,"sourceCode":"    }\n\n    public ObservableList<Pack> getPacks() {\n        return packs;\n    }\n\n    public static void installPack(Path sourceDataPackPath, Path targetDataPackDirectory, GameVersionNumber gameVersionNumber) throws IOException {\n        boolean containsMultiplePacks;\n        Set<String> packs = new HashSet<>();\n        try (FileSystem fs = CompressingUtils.readonly(sourceDataPackPath).setAutoDetectEncoding(true).build()) {\n            Path dataPacks = fs.getPath(\"datapacks\");\n            Path mcmeta = fs.getPath(\"pack.mcmeta\");\n\n            if (Files.exists(dataPacks)) {\n                containsMultiplePacks = true;\n            } else if (Files.exists(mcmeta)) {\n                containsMultiplePacks = false;\n            } else {\n                throw new IOException(\"Malformed datapack zip\");\n            }\n\n            if (containsMultiplePacks) {\n                try (Stream<Path> s = Files.list(dataPacks)) {\n                    packs = s.map(FileUtils::getNameWithoutExtension).collect(Collectors.toSet());\n                }\n            } else {\n                packs.add(FileUtils.getNameWithoutExtension(sourceDataPackPath));\n            }\n\n            try (DirectoryStream<Path> stream = Files.newDirectoryStream(targetDataPackDirectory)) {\n                for (Path dir : stream) {\n                    String packName = FileUtils.getName(dir);\n                    if (FileUtils.getExtension(dir).equals(DISABLED_EXT)) {\n                        packName = StringUtils.removeSuffix(packName, \".\" + DISABLED_EXT);\n                    }\n                    packName = FileUtils.getNameWithoutExtension(packName);\n                    if (packs.contains(packName)) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/addon/datapack/DataPack.java#L56-L92","documentation":"DataPack.installPack inspects a datapack archive to determine its layout: a 'datapacks' subdirectory means the zip contains multiple packs, a pack.mcmeta at the root means a single pack. If neither exists, the archive does not match any known datapack structure and this IOException is thrown.","triggerScenarios":"Calling installPack on a zip file whose root contains neither a datapacks/ directory nor a pack.mcmeta — i.e. the file is not a valid Minecraft datapack.","commonSituations":"User selects the wrong file (a resource pack, mod, or random zip) in the datapack importer; a corrupted/partially downloaded datapack zip; a pack nested one level too deep so mcmeta sits in a subfolder.","solutions":["Verify the zip contains pack.mcmeta at its root (or a datapacks/ folder) before importing","Re-download the datapack from its source — the archive may be corrupted","Unwrap nested folders: if the zip contains a folder/pack.mcmeta, rezip so pack.mcmeta is at the root","Check you selected a datapack, not a resource pack or mod file"],"exampleFix":"// before: mypack.zip -> mypack/pack.mcmeta (nested)\n// after: rezip so structure is mypack.zip -> pack.mcmeta\nzip -r mypack.zip pack.mcmeta assets data","handlingStrategy":"validation","validationCode":"try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(packFile.toFile())) {\n    boolean hasMcmeta = zip.getEntry(\"pack.mcmeta\") != null;\n    boolean hasDatapacks = zip.getEntry(\"datapacks/\") != null;\n    if (!hasMcmeta && !hasDatapacks) {\n        throw new IllegalArgumentException(packFile + \" is not a valid datapack zip\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    dataPack.installPack(target);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Malformed datapack\")) {\n        LOG.warning(\"Selected file is not a valid datapack (missing pack.mcmeta / datapacks dir)\");\n        // prompt user to pick a correct file\n    }\n}","preventionTips":["Check for pack.mcmeta at the zip root before importing","Distinguish datapacks from resource packs and mods before selection","Rezip nested packs so pack.mcmeta sits at the archive root","Validate downloaded archives for corruption (size/checksum) before install"],"tags":["datapack","zip","minecraft"],"backgroundTag":"schema-validation-failed","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}