Expected behavior
When calling:
boolean success = Bukkit.unloadWorld(world, false);
and receiving success = true, we expect the world to be unloaded without being saved.
This means the world will be unloaded as is, without first saving any of it's files.
Observed/Actual behavior
When unloading via
boolean success = Bukkit.unloadWorld(world, false);
the world gets unloaded correctly. But not before the server tries to save raids.dat in the incorrect location. The server thinks the world is in its root.
I've observed this by not having the world folder in the server's root folder and am getting the following error for a world stored in /plugins/pluginname/worlds/MZ:
[09:54:57 ERROR]: Could not save data to raids.dat java.nio.file.NoSuchFileException: ./MZ/data/raids.dat at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?] at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261) ~[?:?] at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482) ~[?:?] at java.base/java.nio.file.Files.newOutputStream(Files.java:227) ~[?:?] at net.minecraft.nbt.NbtIo.writeCompressed(NbtIo.java:76) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.tryWrite(DimensionDataStorage.java:185) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.lambda$scheduleSave$3(DimensionDataStorage.java:163) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]
Steps/models to reproduce
Create a world via a plugin, that saves the world in a folder other than the server's root folder.
(So /plugins/pluginfolder/worlds)
IN GAME: hop into the world to load some chunks, teleport out to a different loaded world.
Unload the world with the 'save: false' flag.
View the console.
Plugin and Datapack List
Paper 1.21.4 (latest release)
Plugins: only the one with the behaviour mentioned above.
Paper version
[10:00:56 INFO]: Checking version, please wait...
[10:00:56 INFO]: This server is running Paper version 1.21.4-188-main@8de7e35 (2025-03-03T16:59:40Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Other
I'm also deleting the world, but only after three seconds post unload. The issue appears to originate from ChunkHolderManager. Here's a sequence of events triggered by command:
[09:54:57 INFO]: [[Maze]] Preparing to unload world: MZ [09:54:57 ERROR]: Could not save data to raids.dat java.nio.file.NoSuchFileException: ./MZ/data/raids.dat at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?] at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261) ~[?:?] at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482) ~[?:?] at java.base/java.nio.file.Files.newOutputStream(Files.java:227) ~[?:?] at net.minecraft.nbt.NbtIo.writeCompressed(NbtIo.java:76) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.tryWrite(DimensionDataStorage.java:185) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.lambda$scheduleSave$3(DimensionDataStorage.java:163) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?] [09:54:57 INFO]: [ChunkHolderManager] Waiting 60s for chunk system to halt for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Halted chunk system for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Waiting 60s for chunk I/O to halt for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Halted I/O scheduler for world 'MZ' [09:54:57 INFO]: [[Maze]] Successfully unloaded world: MZ [09:55:05 INFO]: [[Maze]] Deleted temporary world folder: MZ
Expected behavior
When calling:
boolean success = Bukkit.unloadWorld(world, false);and receiving success = true, we expect the world to be unloaded without being saved.
This means the world will be unloaded as is, without first saving any of it's files.
Observed/Actual behavior
When unloading via
boolean success = Bukkit.unloadWorld(world, false);the world gets unloaded correctly. But not before the server tries to save raids.dat in the incorrect location. The server thinks the world is in its root.
I've observed this by not having the world folder in the server's root folder and am getting the following error for a world stored in /plugins/pluginname/worlds/MZ:
[09:54:57 ERROR]: Could not save data to raids.dat java.nio.file.NoSuchFileException: ./MZ/data/raids.dat at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?] at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261) ~[?:?] at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482) ~[?:?] at java.base/java.nio.file.Files.newOutputStream(Files.java:227) ~[?:?] at net.minecraft.nbt.NbtIo.writeCompressed(NbtIo.java:76) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.tryWrite(DimensionDataStorage.java:185) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.lambda$scheduleSave$3(DimensionDataStorage.java:163) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?]Steps/models to reproduce
Create a world via a plugin, that saves the world in a folder other than the server's root folder.
(So /plugins/pluginfolder/worlds)
IN GAME: hop into the world to load some chunks, teleport out to a different loaded world.
Unload the world with the 'save: false' flag.
View the console.
Plugin and Datapack List
Paper 1.21.4 (latest release)
Plugins: only the one with the behaviour mentioned above.
Paper version
[10:00:56 INFO]: Checking version, please wait...
[10:00:56 INFO]: This server is running Paper version 1.21.4-188-main@8de7e35 (2025-03-03T16:59:40Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Other
I'm also deleting the world, but only after three seconds post unload. The issue appears to originate from ChunkHolderManager. Here's a sequence of events triggered by command:
[09:54:57 INFO]: [[Maze]] Preparing to unload world: MZ [09:54:57 ERROR]: Could not save data to raids.dat java.nio.file.NoSuchFileException: ./MZ/data/raids.dat at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?] at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?] at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261) ~[?:?] at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482) ~[?:?] at java.base/java.nio.file.Files.newOutputStream(Files.java:227) ~[?:?] at net.minecraft.nbt.NbtIo.writeCompressed(NbtIo.java:76) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.tryWrite(DimensionDataStorage.java:185) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at net.minecraft.world.level.storage.DimensionDataStorage.lambda$scheduleSave$3(DimensionDataStorage.java:163) ~[paper-1.21.4.jar:1.21.4-188-8de7e35] at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?] at java.base/java.lang.Thread.run(Thread.java:1583) ~[?:?] [09:54:57 INFO]: [ChunkHolderManager] Waiting 60s for chunk system to halt for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Halted chunk system for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Waiting 60s for chunk I/O to halt for world 'MZ' [09:54:57 INFO]: [ChunkHolderManager] Halted I/O scheduler for world 'MZ' [09:54:57 INFO]: [[Maze]] Successfully unloaded world: MZ [09:55:05 INFO]: [[Maze]] Deleted temporary world folder: MZ