HMCL-dev/HMCL · error · WorldLockedException
The world has been locked
Error message
The world has been locked
What it means
World.delete() refuses to delete a Minecraft save directory while a session.lock file lock is held on it. HMCL guards deletion this way so it never yanks the world out from under a running game process that has the world open. It throws WorldLockedException (an IOException subclass) carrying the world directory path.
Solutions
- Close the running Minecraft instance that has this world open, then retry delete()
- Check for orphaned Java processes still holding session.lock and kill them (lsof/handle.exe)
- Close other programs (antivirus scan, backup sync) holding session.lock open and retry
- Catch WorldLockedException and surface a 'world is in use' message instead of retrying delete
Example fix
// before
world.delete();
// after
try {
world.delete();
} catch (WorldLockedException e) {
UI.warn("World is in use by a running game; close it first.");
} Defensive patterns
Strategy: try-catch
Validate before calling
if (world.isLocked()) {
throw new IllegalStateException("World is in use; close the game first");
}
world.delete(); Try / catch
try {
world.delete();
} catch (WorldLockedException e) {
notifyUserWorldInUse(world.getFile().toString());
} Prevention
- Close the Minecraft instance before deleting a world
- Check world.isLocked() before destructive operations
- Kill orphaned java processes holding session.lock
- Avoid running backups/AV that keep session.lock open during deletes
When it happens
Trigger: Calling World.delete() on a world whose session.lock is currently locked by another process (typically a running Minecraft instance), i.e. World.isLocked() returns true at the moment of the call.
Common situations: User tries to delete a world from the launcher while that world's Minecraft instance is still running or crashed without releasing its lock; an orphaned JVM holds the file lock; on Windows the file is also held open by an antivirus or backup tool.
Related errors
- Failed to close session lock channel of the world
- Not a valid world zip file since level.dat or…
- Path cannot be recognized as a Minecraft world
- Not a valid world directory
- World already exists
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/1fa3d224535a2954.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java:368
}
new World(worldDir).rename(name);
} else if (Files.isDirectory(file)) {
FileUtils.copyDirectory(file, worldDir);
}
}
public void export(Path zip, String worldName) throws IOException {
if (!Files.isDirectory(file))
throw new IOException();
try (Zipper zipper = new Zipper(zip)) {
zipper.putDirectory(file, worldName);
}
}
public void delete() throws IOException {
if (isLocked()) {
throw new WorldLockedException("The world " + getFile() + " has been locked");
}
FileUtils.forceDelete(file);
}
public void copy(String newName) throws IOException {
if (!Files.isDirectory(file)) {
throw new IOException("Not a valid world directory");
}
if (isLocked()) {
throw new WorldLockedException("The world " + getFile() + " has been locked");
}
Path newPath = file.resolveSibling(newName);
FileUtils.copyDirectory(file, newPath, path -> !path.contains("session.lock"));
World newWorld = new World(newPath);
newWorld.rename(newName);
}View on GitHub (pinned to 24702dc5a0)