{"record":{"id":"c3faade945a2359e","repo":"abiosoft/colima","slug":"invalid-directory-w","errorCode":null,"errorMessage":"invalid directory: %w","messagePattern":"invalid directory: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"daemon/process/inotify/watch.go","lineNumber":36,"sourceCode":"\t// An error is returned when the watcher can not be started in background.\n\t//\n\t// The watcher terminates on fatal error or when ctx is done.\n\tWatch(ctx context.Context, dirs []string, c chan<- modEvent) error\n}\n\ntype defaultWatcher struct {\n\tlog *logrus.Entry\n}\n\n// Watch implements dirWatcher\nfunc (d *defaultWatcher) Watch(ctx context.Context, dirs []string, mod chan<- modEvent) error {\n\tlog := d.log\n\tc := make(chan notify.EventInfo, 1)\n\n\tfor _, dir := range dirs {\n\t\tdir, err := util.CleanPath(dir)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid directory: %w\", err)\n\t\t}\n\t\terr = notify.Watch(dir+\"...\", c, notify.Write)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error watching directory recursively '%s': %w\", dir, err)\n\t\t}\n\t}\n\n\tgo func(ctx context.Context, c chan notify.EventInfo, mod chan<- modEvent) {\n\t\tfor {\n\t\t\tselect {\n\n\t\t\tcase <-ctx.Done():\n\t\t\t\tnotify.Stop(c)\n\t\t\t\tlog.Trace(\"stopping watcher\")\n\t\t\t\tif err := ctx.Err(); err != nil {\n\t\t\t\t\tlog.Trace(fmt.Errorf(\"error found in ctx: %w\", err))\n\t\t\t\t\treturn\n\t\t\t\t}","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/abiosoft/colima/blob/c3a5f9184d83a197184f897a9f07eb3c01b3bc88/daemon/process/inotify/watch.go#L18-L54","documentation":"defaultWatcher.Watch sanitizes every directory it is about to register with util.CleanPath (env expansion, ~ expansion, then absolute-path enforcement). A path that is not absolute after expansion fails as 'invalid directory: relative paths not supported for mount ...'. The error returns from Watch and reaches the user only via the logged 'error running watcher' (error 105), so watching silently degrades for the whole volume set.","triggerScenarios":"a container volume Source that does not resolve to an absolute path; '~'-relative sources expanded against the root daemon's HOME (/var/root) instead of the user's; env vars unset in the daemon's sterile environment.","commonSituations":"containers mounting unusual paths; HOME differences between the interactive shell and the privileged daemon process.","solutions":["locate the offending path in the wrapped 'invalid directory' message and fix the container's -v mount to an absolute path","restart colima after fixing so the volume list is rebuilt","keep container mount sources within the host directories already configured as colima mounts"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, dir := range dirs {\n    if p, err := util.CleanPath(dir); err != nil || !filepath.IsAbs(p) {\n        continue // skip unwatchable entries instead of failing the whole set\n    }\n    watchable = append(watchable, p)\n}","typeGuard":null,"tryCatchPattern":"if err := watcher.Watch(ctx, vols, mod); err != nil {\n    if strings.Contains(err.Error(), \"invalid directory\") {\n        // a volume Source did not sanitize; expect refresh on next poll\n    }\n}","preventionTips":["mount container volumes with absolute host paths only","keep sources inside directories already configured as colima mounts","remember the daemon runs as root: '~' expands differently than in your shell"],"tags":["inotify","paths","filesystem"],"backgroundTag":null,"analyzedSha":"c3a5f9184d83a197184f897a9f07eb3c01b3bc88","analyzedAt":"2026-08-15T18:58:08.334Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}