Chokidar: The watcher does not recognize file changes when the outer directory got deleted once.

Created on 15 Oct 2020  路  7Comments  路  Source: paulmillr/chokidar

Whenever I create a folder, then remove it, create it again, and then try to add files in the directory, the watcher does not recognize any file changes.

Versions:

  • Chokidar version 6.14.7
  • Node version v14.12.0
  • OS version: ManjaroLinux 20.1.1 (But I also tried it on windows though)

To Reproduce:

index.js:

const chokidar = require("chokidar");
const watcher = chokidar.watch("test", { persistent: true });
watcher.on("all", (a, b) => console.log(a, b));

execute it. Then...

mkdir test
mkdir test/dir
rm -r test/dir
mkdir test/dir
touch test/dir/file

output:

addDir test
addDir test/dir
unlinkDir test/dir
addDir test/dir

Expected behavior

output:

addDir test
addDir test/dir
unlinkDir test/dir
addDir test/dir
add test/dir/file

All 7 comments

I have exactly the same problem. That raises the question for me how this can come about.

Are the paths cached in the background and not properly deleted from the cache when the underlying file system structure changes? Or what exactly is the explanation for this, because the same problem occurs with the activated option 'usePolling: true'. So it cannot be explained by a missing event from the filesystem.

Some information about the implementation would be very helpful to understand this behavior.

Thanks in advance.

Hi guys,
I also really have to struggle with this problem because I use Chokidar to watch many different shares that are filled by other applications that in turn reuse defined folder structures. Therefore I have to restart Chokidar after each transaction, which is very risky.

I would also appreciate help with this behavior.

I think I found an already closed issue #404 to our problem.

It seems the 'rename' event of the fs.watch is not delegated or interpreted by chokidar.

From the documentation of fs.watch:

On most platforms, 'rename' is emitted whenever a filename appears or disappears in the directory.

This should be fixed somehow, ...

After some investigation, I was able to reproduce and fix the bug!

Problem:

If a relative path was passed when calling chokidar.watch, it was processed internally as a symlink.

Unfortunately, there was a bug in the handling of symlinks, which were never removed from the internal collection when the target path was deleted. This then resulted in an incorrect state when the path was recreated.

Workaround for the current version:

Only use absolute paths as watch directory and avoid watching folders with symlinks.

Solution:

There are several possible solutions to fix the error. In my merge request, I decided to take the most obvious and minimally invasive approach. I simply added a line of code to remove the symlinks from the collection if the target path was removed.

However, at first glance I don't see any reason why a relative path has to be recognized as a symlink.
On the other hand, my approach then solves both the bug #1042 and the problem that symlinks were not cleaned up.

Risk and Recommendation:

Unfortunately, I had to realize that the bug has a larger scope than I had assumed.
Since the symlinks are never cleaned up, the longer the Watcher instance is active, the more often this bug occurs.
For this reason I recommend to merge my bugfix into the official repository as soon as possible, or to solve the bug in another way.

PERFECT! THX!

After some investigation, I was able to reproduce and fix the bug!

Problem:

If a relative path was passed when calling chokidar.watch, it was processed internally as a symlink.

Unfortunately, there was a bug in the handling of symlinks, which were never removed from the internal collection when the target path was deleted. This then resulted in an incorrect state when the path was recreated.

Workaround for the current version:

Only use absolute paths as watch directory and avoid watching folders with symlinks.

Solution:

There are several possible solutions to fix the error. In my merge request, I decided to take the most obvious and minimally invasive approach. I simply added a line of code to remove the symlinks from the collection if the target path was removed.

However, at first glance I don't see any reason why a relative path has to be recognized as a symlink.
On the other hand, my approach then solves both the bug #1042 and the problem that symlinks were not cleaned up.

Risk and Recommendation:

Unfortunately, I had to realize that the bug has a larger scope than I had assumed.
Since the symlinks are never cleaned up, the longer the Watcher instance is active, the more often this bug occurs.
For this reason I recommend to merge my bugfix into the official repository as soon as possible, or to solve the bug in another way.

@paulmillr Thank you very much for processing my MR so quickly.
Can you please provide a new chokidar bugfix version 6.4.4 (npm) with this bugfix?

That would be really great!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

drsavant-pub picture drsavant-pub  路  9Comments

ORESoftware picture ORESoftware  路  8Comments

Pomax picture Pomax  路  3Comments

ahmadnassri picture ahmadnassri  路  6Comments

RedMickey picture RedMickey  路  4Comments