{"record":{"id":"9ab9c169d8b2a50c","repo":"docker/compose","slug":"os-stat-q-w","errorCode":null,"errorMessage":"os.Stat(%q): %w","messagePattern":"os\\.Stat\\(%q\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/watch/paths.go","lineNumber":33,"sourceCode":"*/\n\npackage watch\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\nfunc greatestExistingAncestor(path string) (string, error) {\n\tif path == string(filepath.Separator) ||\n\t\tpath == fmt.Sprintf(\"%s%s\", filepath.VolumeName(path), string(filepath.Separator)) {\n\t\treturn \"\", fmt.Errorf(\"cannot watch root directory\")\n\t}\n\n\t_, err := os.Stat(path)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn \"\", fmt.Errorf(\"os.Stat(%q): %w\", path, err)\n\t}\n\n\tif os.IsNotExist(err) {\n\t\treturn greatestExistingAncestor(filepath.Dir(path))\n\t}\n\n\treturn path, nil\n}\n","sourceCodeStart":15,"sourceCodeEnd":42,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/watch/paths.go#L15-L42","documentation":"While walking a watch path upward, greatestExistingAncestor stats each candidate. os.Stat returning an error that is NOT os.IsNotExist (for example EACCES on a parent directory, or EIO) cannot be handled by the climb-up logic, so it is wrapped with the offending path for diagnosis. This is a hard environment error, distinct from the expected not-yet-existing path case.","triggerScenarios":"A parent directory in the path chain denying search permission to the current user (stat fails with permission denied), or a filesystem-level I/O error. Triggered during path normalization for the watch subsystem.","commonSituations":"Home-directory paths where an ancestor is mode 000 or owned by another user; NFS/FUSE mounts in a bad state returning EIO; SELinux/AppArmor denying stat; running compose watch over paths inside a broken VM share.","solutions":["Check the exact path in the message: `ls -ld <path>` and fix ownership/permissions (chmod +x the ancestor, or run as a user with search rights).","If the path is on a network/FUSE mount, verify the mount is healthy (`mount | grep <path>`, dmesg) and remount if needed.","Repoint the watch path to a location whose full ancestor chain is accessible."],"exampleFix":"# before: ancestor not traversable\nls -ld /home/otheruser   # drwx------ otheruser\n# after\nsudo chmod o+x /home/otheruser   # or move the project under your own home","handlingStrategy":"try-catch","validationCode":"// pre-check the full ancestor chain is traversable\nfor dir := path; ; dir = filepath.Dir(dir) {\n    if _, err := os.Stat(dir); err != nil && !os.IsNotExist(err) {\n        return fmt.Errorf(\"cannot stat %q: %w\", dir, err)\n    }\n    if dir == filepath.Dir(dir) { break }\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) && os.IsPermission(pathErr) {\n        // surface a permission-specific hint with the path from pathErr.Path\n    }\n    return err\n}","preventionTips":["Keep project directories under the user's own home to avoid permission-denied ancestors.","Avoid watching paths that traverse other users' directories.","Monitor mount health for network filesystems used as watch roots."],"tags":["go","docker-compose","watch","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}