Skip to content

Inotify: Removing a subdirectory in a recursively watched directory and then unwatching causes an error #709

@sarowish

Description

@sarowish

System details

  • OS/Platform name and version: Arch Linux
  • Rust version (if building from source): rustc --version: rustc 1.89.0 (29483883e 2025-08-04)
  • Notify version (or commit hash if building from git): 8.2.0
  • On Linux: Kernel version: 6.16.1-arch1-1

What you did (as detailed as you can)

  1. Recursively watch directory a
  2. Remove subdirectory b
  3. Unwatch directory a

Code to reproduce:

use notify::{Config, INotifyWatcher, RecursiveMode, Result, Watcher};
use std::path::PathBuf;

fn main() -> Result<()> {
    let path = PathBuf::from(".");
    let subdirectory_path = path.join("some_dir");
    std::fs::create_dir(&subdirectory_path)?;

    let mut watcher = INotifyWatcher::new(|_| (), Config::default())?;
    watcher.watch(&path, RecursiveMode::Recursive)?;
    std::fs::remove_dir(subdirectory_path)?;
    watcher.unwatch(&path).unwrap();

    Ok(())
}

What you expected

No crash

What happened

Crashed with the output:

thread 'main' panicked at src/main.rs:12:28:
called `Result::unwrap()` on an `Err` value: Error { kind: Io(Os { code: 22, kind: InvalidInput, message: "Invalid argument" }), paths: ["/home/username/test/./some_dir"] }

When the subdirectory gets removed, there is an attempt to remove its descriptor from the inotify instance but this fails since it has already been automatically removed and no longer exists. Consequently, the function returns early and doesn't execute self.paths.remove(&w);, leaving the subdirectory descriptor in self.paths. This error is discarded.

When unwatching the parent directory, there is another attempt to remove it. This time the error is not discarded and the app panics.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions