Skip to content
This repository was archived by the owner on Sep 30, 2026. It is now read-only.
This repository was archived by the owner on Sep 30, 2026. It is now read-only.

Panic in file watcher: index out of bounds at watcher.rs:14 on bursts of filesystem events #28

Description

@kleinpetr

Summary

handle_event in src-tauri/src/file_search/watcher.rs indexes debounced_event.event.paths[0] without checking whether paths is empty. notify emits events with an empty paths vector (e.g. rescan/overflow events), which panics the tokio worker and aborts the app with SIGABRT.

thread 'tokio-runtime-worker' panicked at src/file_search/watcher.rs:14:44:
index out of bounds: the len is 0 but the index is 0

Environment

  • Flare 0.1.0 (flare_0.1.0_amd64.AppImage, official release build)
  • Ubuntu 26.04 LTS, kernel 6.17 x86_64, GNOME on Wayland
  • fs.inotify.max_user_watches = 65536, max_queued_events = 16384

Reproduction

Reproduced 3/3. The minimal case needs only a small HOME — a burst of filesystem events is enough, a large directory tree is not required.

SB=/tmp/flare-repro
rm -rf $SB; mkdir -p $SB/.cache $SB/.local/share $SB/Documents $SB/Desktop
HOME=$SB XDG_CACHE_HOME=$SB/.cache XDG_DATA_HOME=$SB/.local/share \
  ./flare_0.1.0_amd64.AppImage > $SB/run.log 2>&1 &

sleep 30   # wait for "Finished initial file index build"

# burst of events, comfortably above max_queued_events (16384)
printf "$SB/Documents/burst/b%s\n" $(seq 1 25000) | xargs -P 8 -n 1000 mkdir -p

The process panics and aborts. At the moment of the burst it held only 31 inotify watches and HOME contained 4 directories, so this is not related to exhausting max_user_watches.

Also reproduces without any burst if HOME simply contains a large pre-existing tree (~24k directories) at startup — the panic follows shortly after Finished initial file index build.

Root cause

async fn handle_event(app_handle: AppHandle, debounced_event: DebouncedEvent) {
    let manager = app_handle.state::<FileSearchManager>();
    let path = &debounced_event.event.paths[0];   // <-- line 14, unchecked

notify::Event::paths is a Vec<PathBuf> that is legitimately empty for some event kinds. Since the watcher is registered with RecursiveMode::Recursive over the whole of HOME, high event volume makes these events likely in normal use.

Suggested fix

Skip events that carry no path:

let Some(path) = debounced_event.event.paths.first() else {
    return;
};

A Rescan/overflow event might also be worth handling explicitly by re-running the index build, since at that point the in-memory index may be stale.

Possibly related: file watcher thread pegs one core

On a real home directory (~30k directories, which Flare registers as ~60k inotify watches) the notify-rs inoti thread sits at a constant 100% CPU indefinitely — it does not settle after Finished initial file index build, and persists across restarts.

Measured on the same machine:

HOME size watches notify-rs inoti CPU
4 dirs 31 ~0%
~30k dirs (real home) ~60k 100%, sustained

Total system watches were 61,587 of 65,536, so the limit was not reached, and the count kept creeping up slowly rather than stalling at a ceiling — so it does not look like watch exhaustion. I could not confirm the exact spin location (ptrace_scope=1 blocked attaching to the thread), so I am listing this as an observation rather than a diagnosis; it may or may not share a root cause with the panic above.

Dependencies involved: notify 6.1.1, notify-debouncer-full 0.3.2.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions