{"record":{"id":"949de78f86a15b4b","repo":"HMCL-dev/HMCL","slug":"not-a-valid-world-zip-file","errorCode":null,"errorMessage":"Not a valid world zip file","messagePattern":"Not a valid world zip file","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java","lineNumber":94,"sourceCode":"                try (InputStream inputStream = Files.newInputStream(iconFile)) {\n                    icon = new Image(inputStream, 64, 64, true, false);\n                    if (icon.isError())\n                        throw icon.getException();\n                } catch (Exception e) {\n                    LOG.warning(\"Failed to load world icon\", e);\n                }\n            }\n        } else if (Files.isRegularFile(file))\n            try (FileSystem fs = CompressingUtils.readonly(this.file).setAutoDetectEncoding(true).build()) {\n                Path root;\n                if (Files.isRegularFile(fs.getPath(\"/level.dat\"))) {\n                    root = fs.getPath(\"/\");\n                    fileName = FileUtils.getName(this.file);\n                } else {\n                    try (Stream<Path> filesStream = Files.list(fs.getPath(\"/\"))) {\n                        List<Path> files = filesStream.toList();\n                        if (files.size() != 1 || !Files.isDirectory(files.get(0))) {\n                            throw new IOException(\"Not a valid world zip file\");\n                        }\n\n                        root = files.get(0);\n                        fileName = FileUtils.getName(root);\n                    }\n                }\n\n                Path levelDat = root.resolve(\"level.dat\");\n                if (!Files.exists(levelDat)) { //version 20w14infinite\n                    levelDat = root.resolve(\"special_level.dat\");\n                }\n                if (!Files.exists(levelDat)) {\n                    throw new IOException(\"Not a valid world zip file since level.dat or special_level.dat cannot be found.\");\n                }\n                loadAndCheckLevelData(levelDat);\n\n                Path iconFile = root.resolve(\"icon.png\");\n                if (Files.isRegularFile(iconFile)) {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java#L76-L112","documentation":"When a world file is a zip, the constructor expects either level.dat/special_level.dat at the zip root or exactly one top-level directory containing them. Otherwise it cannot locate the world root and throws IOException 'Not a valid world zip file'.","triggerScenarios":"Opening a zip whose root holds level.dat plus sibling files (screenshot zips, multi-world archives, zips made on macOS with __MACOSX folders), or a zip with multiple top-level directories.","commonSituations":"Users zipping multiple worlds together, browser downloading a page-wrapped zip, macOS Finder zips adding extra root entries, modpack exports with README at root.","solutions":["Re-zip so the archive contains exactly one top-level directory holding level.dat","Extract the zip and import via the directory path instead","Remove stray root-level files (e.g. __MACOSX, README) and keep a single world folder","Download the world zip again from the original source"],"exampleFix":"// before\nworld.zip\n├── level.dat\n├── region/\n└── screenshot.png   // extra root entries -> rejected\n// after\nworld.zip\n└── MyWorld/\n    ├── level.dat\n    └── region/","handlingStrategy":"validation","validationCode":"try (FileSystem fs = FileSystems.newFileSystem(zipPath)) {\n    try (Stream<Path> s = Files.list(fs.getPath(\"/\"))) {\n        List<Path> top = s.toList();\n        boolean ok = top.size() == 1 && Files.isDirectory(top.get(0))\n            && Files.exists(top.get(0).resolve(\"level.dat\"));\n        if (!ok) throw new IllegalArgumentException(\"Zip must contain exactly one world folder with level.dat\");\n    }\n}","typeGuard":"static boolean isValidWorldZip(Path zip) {\n    try (FileSystem fs = FileSystems.newFileSystem(zip)) {\n        try (Stream<Path> s = Files.list(fs.getPath(\"/\"))) {\n            List<Path> top = s.toList();\n            return top.size() == 1 && Files.isDirectory(top.get(0))\n                && Files.exists(top.get(0).resolve(\"level.dat\"));\n        }\n    } catch (IOException e) { return false; }\n}","tryCatchPattern":"try {\n    World w = new World(zipFile);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Not a valid world zip file\")) {\n        // extract manually or ask user to re-zip with a single world folder\n    } else throw e;\n}","preventionTips":["Zip the world folder itself, not its contents at root","Exclude __MACOSX and metadata files from archives","Only include one world per zip","Preview zip structure before import"],"tags":["zip","filesystem","minecraft"],"backgroundTag":"archive-structure-invalid","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"}