{"record":{"id":"cc3b52dac7b6b61d","repo":"HMCL-dev/HMCL","slug":"not-a-valid-world-directory-since-level-dat-or-spe","errorCode":null,"errorMessage":"Not a valid world directory since level.dat or special_level.dat cannot be found.","messagePattern":"Not a valid world directory since level\\.dat or special_level\\.dat cannot be found\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java","lineNumber":69,"sourceCode":"\n    private CompoundTag worldGenSettingsDataBackingTag; // Use for writing back to the file\n    private CompoundTag normalizedWorldGenSettingsData; // Use for reading/modification\n    private Path worldGenSettingsDataPath;\n\n    private CompoundTag playerData; // Use for both reading/modification and writing back to the file\n    private Path playerDataPath;\n\n    public World(Path file) throws IOException {\n        this.file = file;\n\n        if (Files.isDirectory(file)) {\n            fileName = FileUtils.getName(this.file);\n            Path levelDatPath = this.file.resolve(\"level.dat\");\n            if (!Files.exists(levelDatPath)) { // version 20w14infinite\n                levelDatPath = this.file.resolve(\"special_level.dat\");\n            }\n            if (!Files.exists(levelDatPath)) {\n                throw new IOException(\"Not a valid world directory since level.dat or special_level.dat cannot be found.\");\n            }\n            this.levelDataPath = levelDatPath;\n            loadAndCheckWorldData();\n\n            Path iconFile = this.file.resolve(\"icon.png\");\n            if (Files.isRegularFile(iconFile)) {\n                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\"))) {","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java#L51-L87","documentation":"World's constructor validates that the directory is a real Minecraft save by looking for level.dat, falling back to special_level.dat (used by the 20w14infinite snapshot). If neither exists it throws IOException, since world metadata cannot be read.","triggerScenarios":"Calling new World(path) on a directory that lacks both level.dat and special_level.dat.","commonSituations":"Pointing the launcher at a folder that is not a save (e.g. backups dir, 'saves' root itself), partially deleted/corrupted world, unzip that stripped dotfiles, modpack folders mislabeled as worlds.","solutions":["Verify the target path is an actual world directory containing level.dat","Restore level.dat from backup or re-extract the world zip","Move up/down one directory level (user may have selected the wrong folder)","Re-download the world from its source"],"exampleFix":"// before\nnew World(\"saves/\")            // selects the saves root, no level.dat\n// after\nnew World(\"saves/MyWorld\")     // actual world containing level.dat","handlingStrategy":"validation","validationCode":"Path p = Path.of(dir);\nif (!Files.isDirectory(p) || !(Files.exists(p.resolve(\"level.dat\")) || Files.exists(p.resolve(\"special_level.dat\")))) {\n    throw new IllegalArgumentException(\"Not a Minecraft world directory: \" + dir);\n}","typeGuard":"static boolean looksLikeWorldDir(Path p) {\n    return Files.isDirectory(p)\n        && (Files.isRegularFile(p.resolve(\"level.dat\")) || Files.isRegularFile(p.resolve(\"special_level.dat\")));\n}","tryCatchPattern":"try {\n    World w = new World(dir);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"level.dat or special_level.dat\")) {\n        // tell user to select a valid world folder\n    } else throw e;\n}","preventionTips":["Use a directory picker filtered to folders containing level.dat","Check for level.dat before offering a folder as a world","Verify extracted zip contents before import"],"tags":["filesystem","minecraft","world"],"backgroundTag":"file-not-found","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"}