{"record":{"id":"3e70ac3a75e1d91e","repo":"docker/compose","slug":"stat-q-w","errorCode":null,"errorMessage":"stat %q: %w","messagePattern":"stat %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sync/tar.go","lineNumber":81,"sourceCode":"\t\tclient:      client,\n\t}\n}\n\nfunc (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) error {\n\tcontainers, err := t.client.ContainersForService(ctx, t.projectName, service)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar pathsToCopy []PathMapping\n\tvar pathsToDelete []string\n\tfor _, p := range paths {\n\t\tif _, err := os.Stat(p.HostPath); err == nil {\n\t\t\tpathsToCopy = append(pathsToCopy, *p)\n\t\t} else if errors.Is(err, fs.ErrNotExist) {\n\t\t\tpathsToDelete = append(pathsToDelete, p.ContainerPath)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"stat %q: %w\", p.HostPath, err)\n\t\t}\n\t}\n\n\tvar deleteCmd []string\n\tif len(pathsToDelete) != 0 {\n\t\tdeleteCmd = append([]string{\"rm\", \"-rf\"}, pathsToDelete...)\n\t}\n\n\tvar (\n\t\teg    errgroup.Group\n\t\terrMu sync.Mutex\n\t\terrs  = make([]error, 0, len(containers)*2) // max 2 errs per container\n\t)\n\n\teg.SetLimit(16) // arbitrary limit, adjust to taste :D\n\tfor i := range containers {\n\t\tcontainerID := containers[i].ID\n\t\ttarReader := tarArchive(pathsToCopy)","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/internal/sync/tar.go#L63-L99","documentation":"While preparing a tar-based sync, Tar.Sync stats each PathMapping's HostPath to decide whether to copy it or delete its container counterpart. A missing file is expected (treated as a delete), but any other stat failure (permission denied, path too long, I/O error) aborts the whole sync with 'stat %q: %w'. This is a host-filesystem-level error, not a Docker error.","triggerScenarios":"Calling Tar.Sync(ctx, service, paths) where a p.HostPath exists but the process lacks search permission on a parent directory, the path exceeds NAME_MAX, or the underlying filesystem returns an I/O error. Only errors other than fs.ErrNotExist reach this branch.","commonSituations":"Build contexts or volume-sync roots with restrictive ownership (e.g. files created by a root container then synced by a non-root compose run), paths behind broken FUSE/NFS mounts, or a path that is a dangling symlink whose parent dir is unreadable.","solutions":["Check permissions on the failing host path (the error's %q names it exactly); chmod/chown the parent directories so the compose process can traverse them","If the file is intentionally gone, delete the stale entry from your sync path list so it hits the ErrNotExist delete branch cleanly","Unmount or repair broken network/FUSE filesystems that return EIO on stat","Re-run compose watch/sync after fixing; if it persists, stat the path manually with the same user to reproduce outside compose"],"exampleFix":"# shell: reproduce and fix the exact path named in the error\nsudo -u $(whoami) stat /path/from/error   # -> permission denied\nsudo chmod o+x /parent/dir               # grant traversal\n# then re-run: docker compose watch","handlingStrategy":"validation","validationCode":"// before Tar.Sync: verify every host path is stat-able apart from clean NotExist\nfor _, p := range paths {\n    if _, err := os.Stat(p.HostPath); err != nil && !errors.Is(err, fs.ErrNotExist) {\n        return fmt.Errorf(\"pre-check failed for %s: %w\", p.HostPath, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"// inspect errors from Tar.Sync with errors.Is/As against fs.ErrPermission to distinguish permission vs I/O causes\nif err := syncer.Sync(ctx, svc, paths); err != nil {\n    var pathErr *fs.PathError\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, fs.ErrPermission) { /* fix perms */ }\n}","preventionTips":["Keep sync roots owned by the user running compose","Avoid syncing into paths containing root-owned artifacts from other containers","Prefer local filesystems over flaky network mounts for watch/sync sources"],"tags":["filesystem","sync","permissions","tar","go"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}