Have you used AI?
No
Bug Description
When Watchpack is initialized with startTime: Date.now(), it fires the change event for directories / files that were created shortly before.
When startTime is not set, the change event is not fired as desired (fixed with test coverage in #150).
README.md documents startTime as being an optional number, and "Watching can be started in the past. This way watching can start after file reading.". The observed behavior of getting unwanted events is surprising.
Moreover, the source shows that FS_ACCURACY (up to two seconds!) is added to the start time. Any file/directory older than this time will be flagged as changed. This is not documented and surprising (and contributing to this bug):
|
const safeTime = initial ? Math.min(now, birthtime) + FS_ACCURACY : now; |
The above source also shows the use of birthtime/btime instead of ctime. This is surprising and not documented in README.
I tried using fs.utimes with a past date as a work-around. This works on macOS but failed on Linux and Windows, because fs.utimes updates mtime but not btime. The use of btime appears to be introduced in #183. The work-around works in watchpack@2.0.1 (which is before 2.1.0 that includes #183).
Link to Minimal Reproduction and step to reproduce
npm install watchpack ( tested with latest version watchpack@2.5.1 and Node 25.9.0)
Save following file as test.mjs and run node test.mjs:
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import Watchpack from "watchpack";
const base = path.join(os.tmpdir(), "watchpack_repro");
await fs.rm(base, { recursive: true }).catch(() => {}); // ignore ENOENT
await fs.mkdir(base);
await fs.mkdir(path.join(base, "subdir"));
const dateInPast = Date.now() / 1000 - 10; // 10 seconds older should be plenty
// await fs.utimes(path.join(base, 'subdir'), dateInPast, dateInPast);
// ^ Works on macOS (changes btime), not on Linux or Windows. Also works in watchpack<=2.0.1
const w = new Watchpack({});
w.on("change", console.log);
w.watch({
directories: [base],
missing: [],
startTime: Date.now(),
});
console.log("Waiting 2 seconds. Should not log anything.");
await new Promise(r => setTimeout(r, 2000));
w.close();
Expected Behavior
Should not log change events for files/directories that were created shortly before Watchpack is initialized.
Actual Behavior
Logs a change event for the subdirectory that was created immediately before:
/tmp/watchpack_repro/subdir 1777218474762 scan (dir)
(the minimal STR uses a directory, but this also reproduces for files)
Environment
Node: v25.9.0 (and also tested v20.20.2)
Linux: Ubuntu 24.04.4 LTS
macOS: 15.7.5
Is this a regression?
No
Last Working Version
No response
Additional Context
The fs.utimes work-around to get the test to pass works on macOS because it apparently changes the btime as well:
$ mkdir d;node -e 'require("fs/promises").utimes("d", 1234, 5678)';stat -x d
...
Access: Thu Jan 1 01:20:34 1970
Modify: Thu Jan 1 02:34:38 1970
Change: Sun Apr 26 18:19:50 2026
Birth: Thu Jan 1 02:34:38 1970
On Linux, the Birth time is not modified when I run the same command.
Have you used AI?
No
Bug Description
When
Watchpackis initialized withstartTime: Date.now(), it fires thechangeevent for directories / files that were created shortly before.When
startTimeis not set, thechangeevent is not fired as desired (fixed with test coverage in #150).README.md documents
startTimeas being an optional number, and "Watching can be started in the past. This way watching can start after file reading.". The observed behavior of getting unwanted events is surprising.Moreover, the source shows that
FS_ACCURACY(up to two seconds!) is added to the start time. Any file/directory older than this time will be flagged as changed. This is not documented and surprising (and contributing to this bug):watchpack/lib/DirectoryWatcher.js
Line 430 in 59adaaa
The above source also shows the use of birthtime/btime instead of ctime. This is surprising and not documented in README.
I tried using
fs.utimeswith a past date as a work-around. This works on macOS but failed on Linux and Windows, becausefs.utimesupdatesmtimebut notbtime. The use ofbtimeappears to be introduced in #183. The work-around works inwatchpack@2.0.1(which is before 2.1.0 that includes #183).Link to Minimal Reproduction and step to reproduce
npm install watchpack( tested with latest versionwatchpack@2.5.1and Node 25.9.0)Save following file as
test.mjsand runnode test.mjs:Expected Behavior
Should not log
changeevents for files/directories that were created shortly beforeWatchpackis initialized.Actual Behavior
Logs a change event for the subdirectory that was created immediately before:
(the minimal STR uses a directory, but this also reproduces for files)
Environment
Is this a regression?
No
Last Working Version
No response
Additional Context
The
fs.utimeswork-around to get the test to pass works on macOS because it apparently changes the btime as well:On Linux, the
Birthtime is not modified when I run the same command.