Skip to content

load_folder deadlocks when file watcher detects added/removed files #23954

@amtep

Description

@amtep

Bevy version and features

Tested with 0.18.1 and main branch (bb1d516).

I reproduced it with a modified asset_loading example, default features + dev (for the file watcher)

[Optional] Relevant system information

Rust 1.95.0

SystemInfo { os: "Linux (Debian GNU/Linux)", kernel: "6.19.8+deb14-amd64", cpu: "AMD Ryzen 7 5800X 8-Core Processor", core_count: "8", memory: "15.5 GiB" }

AdapterInfo { name: "AMD Radeon RX 7800 XT (RADV NAVI32)", vendor: 4098, device: 29822, device_type: DiscreteGpu, device_pci_bus_id: "0000:2d:00.0", driver: "radv", driver_info: "Mesa 26.0.2-1", backend: Vulkan, subgroup_min_size: 32, subgroup_max_size: 64, transient_saves_memory: false }

What you did

I modified the asset_loading example to reproduce the problem:

diff --git a/examples/asset/asset_loading.rs b/examples/asset/asset_loading.rs
index 49d2dca27..3d62b2787 100644
--- a/examples/asset/asset_loading.rs
+++ b/examples/asset/asset_loading.rs
@@ -2,6 +2,9 @@
 
 use bevy::{asset::LoadedFolder, prelude::*};
 
+#[derive(Resource)]
+struct FolderResource(Handle<LoadedFolder>);
+
 fn main() {
     App::new()
         .add_plugins(DefaultPlugins)
@@ -52,7 +55,8 @@ fn setup(
     // to load.
     // If you want to keep the assets in the folder alive, make sure you store the returned handle
     // somewhere.
-    let _loaded_folder: Handle<LoadedFolder> = asset_server.load_folder("models/torus");
+    let loaded_folder: Handle<LoadedFolder> = asset_server.load_folder("models/torus");
+    commands.insert_resource(FolderResource(loaded_folder));
 
     // If you want a handle to a specific asset in a loaded folder, the easiest way to get one is to call load.
     // It will _not_ be loaded a second time.

Then I ran cargo run -F dev --example asset_loading and waited for the window to load, then ran touch assets/models/torus/testing.gltf to trigger a reload.

What went wrong

The game printed 2026-04-23T17:53:13.609789Z INFO bevy_asset::server: Reloading folder models/torus because the content has changed and then stopped responding to input. Even hitting the close button on the window frame led to a pause, then my window manager offering to kill the process.

(Well, the example doesn't accept input anyway. Hitting the close button is how I verified it had the same problem as my game.)

Additional information

I traced the execution to this line, which is where it stops:

crates/bevy_asset/src/server/mod.rs:
self.write_infos().stats.started_load_tasks += 1;

in load_folder_internal.

It's called from handle_internal_asset_events, which already holds the lock to infos.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-AssetsLoad files from disk to use for things like images, models, and soundsC-BugAn unexpected or incorrect behaviorS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions