Unloading a world does not stop raids.dat from being saved.
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 3.5k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 11
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing world unload handling in ChunkHolderManager and the save scheduling path in DimensionDataStorage, using the reported stack trace as the entry point. Reproduce with a plugin-created world outside the server root and Bukkit.unloadWorld(world, false). Done means unloading succeeds without attempting to write raids.dat to the wrong location.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100