{"record":{"id":"cfdbda6d13c3f980","repo":"HMCL-dev/HMCL","slug":"world-already-exists","errorCode":null,"errorMessage":"World already exists","messagePattern":"World already exists","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java","lineNumber":327,"sourceCode":"\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)) {\n            throw new FileAlreadyExistsException(\"World already exists\");\n        }\n\n        if (Files.isRegularFile(file)) {\n            try (FileSystem fs = CompressingUtils.readonly(file).setAutoDetectEncoding(true).build()) {\n                Path levelDatPath = fs.getPath(\"/level.dat\");\n                if (Files.isRegularFile(levelDatPath)) {\n                    fileName = FileUtils.getName(file);\n\n                    new Unzipper(file, worldDir).unzip();\n                } else {\n                    try (Stream<Path> stream = Files.list(fs.getPath(\"/\"))) {\n                        List<Path> subDirs = stream.toList();\n                        if (subDirs.size() != 1) {\n                            throw new IOException(\"World zip malformed\");\n                        }\n                        String subDirectoryName = FileUtils.getName(subDirs.get(0));\n                        new Unzipper(file, worldDir)\n                                .setSubDirectory(\"/\" + subDirectoryName + \"/\")","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java#L309-L345","documentation":"World.install throws FileAlreadyExistsException(\"World already exists\") when the target directory saves/<name> already exists as a directory, refusing to overwrite an existing world. This is a guard against silently destroying another world's data.","triggerScenarios":"Calling world.install(savesDir, name) where Files.isDirectory(savesDir.resolve(name)) is true, e.g. installing a world whose name matches an existing world folder.","commonSituations":"Re-importing a world that is already installed, two different zips sharing the same LevelName, running an import script twice without cleanup, or a leftover partial install directory from a failed previous attempt.","solutions":["Pick a different world name (e.g. append a timestamp) or delete/rename the existing directory first","Check Files.exists(savesDir.resolve(name)) before calling install and prompt the user","If the target is a leftover empty/partial folder from a failed install, remove it and retry"],"exampleFix":"// before\nworld.install(savesDir, \"New World\"); // may already exist\n// after\nPath target = savesDir.resolve(\"New World\");\nif (Files.isDirectory(target)) name = \"New World (\" + System.currentTimeMillis() + \")\";\nworld.install(savesDir, name);","handlingStrategy":"validation","validationCode":"static String uniqueWorldName(Path savesDir, String preferred) {\n    if (!Files.isDirectory(savesDir.resolve(preferred))) return preferred;\n    for (int i = 2; ; i++) {\n        String candidate = preferred + \" (\" + i + \")\";\n        if (!Files.isDirectory(savesDir.resolve(candidate))) return candidate;\n    }\n}","typeGuard":"static boolean worldNameTaken(Path savesDir, String name) {\n    return Files.isDirectory(savesDir.resolve(name));\n}","tryCatchPattern":"try {\n    world.install(savesDir, name);\n} catch (FileAlreadyExistsException e) {\n    // prompt user: overwrite (delete target) or pick another name\n}","preventionTips":["Check savesDir/<name> for existence before installing","Uniquify names by appending a counter or timestamp","Clean up leftover directories from failed installs","Never reuse a LevelName from level.dat blindly when importing multiple zips"],"tags":["minecraft","io","conflict","world-install"],"backgroundTag":"file-already-exists","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"}