docker/compose · error

newWatcher: %w

Error message

newWatcher: %w

What it means

On the naive watcher path, newWatcher records each (possibly EncompassingPaths-merged) path as absolute before building the notifyList. filepath.Abs fails only when the process working directory is gone or unreadable, exactly like the darwin variant — relative paths cannot be resolved without a valid cwd. The newWatcher prefix marks the construction site.

Source

Thrown at pkg/watch/watcher_naive.go:323

				"Run 'sysctl fs.inotify.max_user_instances' to check your inotify limits.\n" +
				"To raise them, run 'sudo sysctl fs.inotify.max_user_instances=1024'")
		}
		return nil, fmt.Errorf("creating file watcher: %w", err)
	}
	MaybeIncreaseBufferSize(fsw)

	err = fsw.SetRecursive()
	isWatcherRecursive := err == nil

	wrappedEvents := make(chan FileEvent)
	notifyList := make(map[string]bool, len(paths))
	if isWatcherRecursive {
		paths = pathutil.EncompassingPaths(paths)
	}
	for _, path := range paths {
		path, err := filepath.Abs(path)
		if err != nil {
			return nil, fmt.Errorf("newWatcher: %w", err)
		}
		notifyList[path] = true
	}

	wmw := &naiveNotify{
		notifyList:         notifyList,
		watcher:            fsw,
		events:             fsw.Events,
		wrappedEvents:      wrappedEvents,
		errors:             fsw.Errors,
		isWatcherRecursive: isWatcherRecursive,
	}
	wmw.addWatch = wmw.add

	return wmw, nil
}

var _ Notify = &naiveNotify{}

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Change back to an existing directory (`cd ~/project`) and rerun the command.
  2. Make clean targets delete directory contents, never the watched directory itself.
  3. Recreate the deleted directory if the workflow depends on watching it from inside.
Defensive patterns

Strategy: validation

Validate before calling

// fail fast when cwd is gone (same check the watcher needs)
wd, err := os.Getwd()
if err != nil { return err }
if _, err := os.Lstat(wd); err != nil {
    return fmt.Errorf("current directory %q disappeared; cd back into the project", wd)
}

Prevention

When it happens

Trigger: newWatcher(paths) on Linux/other platforms where isWatcherRecursive collapsed paths via EncompassingPaths, one is relative, and getwd() fails because the cwd was deleted (common when the watched project directory is removed by a clean step while the shell still sits in it).

Common situations: `make clean`/`git clean -xfd` removing the directory the terminal was in; temp-dir-based CI jobs purged mid-run; scripts cd-ing into soon-deleted build output dirs before starting compose watch.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/a28b43c263622c11. Report an issue: GitHub.