HMCL-dev/HMCL · error · IOException
Not a valid world directory since level.dat or…
Error message
Not a valid world directory since level.dat or special_level.dat cannot be found.
What it means
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.
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
Example fix
// before
new World("saves/") // selects the saves root, no level.dat
// after
new World("saves/MyWorld") // actual world containing level.dat Defensive patterns
Strategy: validation
Validate before calling
Path p = Path.of(dir);
if (!Files.isDirectory(p) || !(Files.exists(p.resolve("level.dat")) || Files.exists(p.resolve("special_level.dat")))) {
throw new IllegalArgumentException("Not a Minecraft world directory: " + dir);
} Type guard
static boolean looksLikeWorldDir(Path p) {
return Files.isDirectory(p)
&& (Files.isRegularFile(p.resolve("level.dat")) || Files.isRegularFile(p.resolve("special_level.dat")));
} Try / catch
try {
World w = new World(dir);
} catch (IOException e) {
if (e.getMessage().contains("level.dat or special_level.dat")) {
// tell user to select a valid world folder
} else throw e;
} Prevention
- 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
When it happens
Trigger: Calling new World(path) on a directory that lacks both level.dat and special_level.dat.
Common situations: 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.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Not a valid world zip file
- level.dat missing Data
- level.dat missing LevelName
- level.dat missing LastPlayed
- Not a valid world directory
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/cc3b52dac7b6b61d.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java:69
private CompoundTag worldGenSettingsDataBackingTag; // Use for writing back to the file
private CompoundTag normalizedWorldGenSettingsData; // Use for reading/modification
private Path worldGenSettingsDataPath;
private CompoundTag playerData; // Use for both reading/modification and writing back to the file
private Path playerDataPath;
public World(Path file) throws IOException {
this.file = file;
if (Files.isDirectory(file)) {
fileName = FileUtils.getName(this.file);
Path levelDatPath = this.file.resolve("level.dat");
if (!Files.exists(levelDatPath)) { // version 20w14infinite
levelDatPath = this.file.resolve("special_level.dat");
}
if (!Files.exists(levelDatPath)) {
throw new IOException("Not a valid world directory since level.dat or special_level.dat cannot be found.");
}
this.levelDataPath = levelDatPath;
loadAndCheckWorldData();
Path iconFile = this.file.resolve("icon.png");
if (Files.isRegularFile(iconFile)) {
try (InputStream inputStream = Files.newInputStream(iconFile)) {
icon = new Image(inputStream, 64, 64, true, false);
if (icon.isError())
throw icon.getException();
} catch (Exception e) {
LOG.warning("Failed to load world icon", e);
}
}
} else if (Files.isRegularFile(file))
try (FileSystem fs = CompressingUtils.readonly(this.file).setAutoDetectEncoding(true).build()) {
Path root;
if (Files.isRegularFile(fs.getPath("/level.dat"))) {View on GitHub (pinned to 24702dc5a0)