docker/compose · error
notify.Add(%q): %w
Error message
notify.Add(%q): %w
What it means
In naiveNotify.Add (the non-recursive fallback watcher used when fsnotify lacks recursive support), each candidate path is stat'ed before a watch is added. A stat error that is neither nil nor IsNotExist — permission denial or I/O error — is wrapped with the path name. This mirrors greatestExistingAncestor's logic but happens at registration time.
Source
Thrown at pkg/watch/watcher_naive.go:82
}
pathsToWatch := []string{}
for path := range d.notifyList {
pathsToWatch = append(pathsToWatch, path)
}
pathsToWatch, err := greatestExistingAncestors(pathsToWatch)
if err != nil {
return err
}
if d.isWatcherRecursive {
pathsToWatch = pathutil.EncompassingPaths(pathsToWatch)
}
for _, name := range pathsToWatch {
fi, err := os.Stat(name)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("notify.Add(%q): %w", name, err)
}
// if it's a file that doesn't exist,
// we should have caught that above, let's just skip it.
if os.IsNotExist(err) {
continue
}
if fi.IsDir() {
err = d.watchRecursively(name)
if err != nil {
return fmt.Errorf("notify.Add(%q): %w", name, err)
}
} else {
err = d.addWatch(filepath.Dir(name))
if err != nil {
return fmt.Errorf("notify.Add(%q): %w", filepath.Dir(name), err)
}View on GitHub (pinned to ddc4b044b6)
Solutions
- Check the path from the message with ls -ld and grant the current user read/search permission on it.
- Remove the inaccessible path from the watch set (fix develop.watch entries) if it is not essential.
- Repair the underlying mount/filesystem if stat fails with an I/O error.
Defensive patterns
Strategy: validation
Validate before calling
// verify each watch path is stat-able (or confirmed absent) up front
for _, p := range paths {
if _, err := os.Stat(p); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("path %q not accessible: %w", p, err)
}
} Try / catch
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) && os.IsPermission(pathErr) {
// report pathErr.Path and advise chmod/chown
}
return err // non-permission stat failures are environment faults
} Prevention
- Grant the compose process read access to all watch roots and their ancestors.
- Keep watch paths off failing or stale network mounts.
- Validate watch paths at startup in wrapper scripts.
When it happens
Trigger: d.Add(paths) hitting a path whose stat fails with EACCES/EIO while the naive (non-fsevents, non-recursive fsnotify) watcher registers watches. NotNotExist errors are deliberately skipped (missing files were resolved earlier), so only real stat failures land here.
Common situations: Watch roots under directories with restrictive permissions; paths on failing disks or stale network mounts; Linux systems without recursive inotify support taking this code path (e.g. older kernels or non-Linux non-macOS platforms).
Related errors
- os.Stat(%q): %w
- initializing remote resource cache: %w
- cannot watch root directory
- newWatcher: %w
- watcher.Add(%q): %w
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/37f8f55770452f60.
Report an issue: GitHub.