{"record":{"id":"13554355a8937293","repo":"HMCL-dev/HMCL","slug":"not-a-valid-world-directory","errorCode":null,"errorMessage":"Not a valid world directory","messagePattern":"Not a valid world directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java","lineNumber":308,"sourceCode":"        this.worldGenSettingsDataPath = worldGenSettingsDataPath;\n        this.worldGenSettingsDataBackingTag = worldGenSettingsDataBackingTag;\n        this.normalizedWorldGenSettingsData = unifiedWorldGenSettingsData;\n    }\n\n    private void setPlayerData(Path playerDataPath, CompoundTag playerData) {\n        this.playerDataPath = playerDataPath;\n        this.playerData = playerData;\n    }\n\n    public void reloadWorldData() throws IOException {\n        loadAndCheckWorldData();\n    }\n\n    // The rename method is used to rename temporary world object during installation and copying,\n    // so there is no need to modify the `file` field.\n    public void rename(String newName) throws IOException {\n        if (!Files.isDirectory(file))\n            throw new IOException(\"Not a valid world directory\");\n\n        // Change the name recorded in level.dat\n        dataTag.setString(\"LevelName\", newName);\n        writeLevelData();\n\n        // then change the folder's name\n        Files.move(file, file.resolveSibling(newName));\n    }\n\n    public void install(Path savesDir, String name) throws IOException {\n        Path worldDir;\n        try {\n            worldDir = savesDir.resolve(name);\n        } catch (InvalidPathException e) {\n            throw new IOException(e);\n        }\n\n        if (Files.isDirectory(worldDir)) {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java#L290-L326","documentation":"Thrown by World.rename(String) when the world's underlying file field is not a directory. Rename only works on extracted world folders because it rewrites LevelName in level.dat and then renames the folder; a zip-backed World cannot be renamed this way.","triggerScenarios":"Calling world.rename(\"NewName\") on a World constructed from a zip file, or after the world directory was deleted/moved before the call.","commonSituations":"Renaming a world imported from a zip before it was installed to a saves directory, renaming after manually deleting the folder, or passing a file path instead of a directory to the World constructor.","solutions":["Call install(savesDir, name) on the zip-backed world first, then rename the installed world directory","Ensure the World was constructed from a directory that still exists (Files.isDirectory)","Re-create the World object if the folder was moved or deleted"],"exampleFix":"// before\nWorld world = new World(Path.of(\"world.zip\"));\nworld.rename(\"NewName\"); // throws: not a directory\n// after\nWorld world = new World(Path.of(\"world.zip\"));\nworld.install(Path.of(\".minecraft/saves\"), \"OldName\");\nWorld installed = new World(Path.of(\".minecraft/saves/OldName\"));\ninstalled.rename(\"NewName\");","handlingStrategy":"try-catch","validationCode":"if (!Files.isDirectory(world.getFile())) throw new IllegalStateException(\"rename requires an installed (directory) world\");","typeGuard":"static boolean isRenamable(World w) {\n    return Files.isDirectory(w.getFile());\n}","tryCatchPattern":"try {\n    world.rename(newName);\n} catch (IOException e) {\n    if (String.valueOf(e.getMessage()).equals(\"Not a valid world directory\")) {\n        // install the world into saves first, then rename\n    }\n}","preventionTips":["Only call rename on World objects constructed from directories on disk","Call install(savesDir, name) for zip-backed worlds before renaming","Verify the folder still exists if external tools may have moved it"],"tags":["minecraft","io","world-rename","filesystem"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}